Support user preferences

Users may prefer different decorations for the image links. Allow each
user to overwite the global default. For this a new preference screen
is added.

Change-Id: I9f685cfa47e2ae0194f15a5d9a8655483a6c459d
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/GetConfig.java
index 52635bb..6a488ae 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/GetConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/GetConfig.java
@@ -44,7 +44,7 @@
     return info;
   }
 
-  public class ConfigInfo {
+  public static class ConfigInfo {
     String defaultProject;
     LinkDecoration linkDecoration;
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/GetPreference.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/GetPreference.java
new file mode 100644
index 0000000..532b09d
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/GetPreference.java
@@ -0,0 +1,77 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.imagare;
+
+import com.google.common.base.Objects;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import com.googlesource.gerrit.plugins.imagare.GetConfig.ConfigInfo;
+
+import org.eclipse.jgit.lib.Config;
+
+public class GetPreference implements RestReadView<AccountResource> {
+  public static final String PREFERENCE = "preference";
+  public static final String KEY_DEFAULT_PROJECT = "defaultProject";
+  public static final String KEY_LINK_DECORATION = "linkDecoration";
+
+  private final Provider<IdentifiedUser> self;
+  private final ProjectCache projectCache;
+  private final String pluginName;
+  private final Provider<GetConfig> getConfig;
+
+  @Inject
+  GetPreference(Provider<IdentifiedUser> self, ProjectCache projectCache,
+      @PluginName String pluginName, Provider<GetConfig> getConfig) {
+    this.self = self;
+    this.projectCache = projectCache;
+    this.pluginName = pluginName;
+    this.getConfig = getConfig;
+  }
+
+  @Override
+  public ConfigInfo apply(AccountResource rsrc) throws AuthException {
+    if (self.get() != rsrc.getUser()
+        && !self.get().getCapabilities().canAdministrateServer()) {
+      throw new AuthException("not allowed to get preference");
+    }
+
+    String username = self.get().getUserName();
+
+    ConfigInfo globalCfg = getConfig.get().apply(new ConfigResource());
+
+    Config db =
+        projectCache.getAllProjects().getConfig(pluginName + ".config").get();
+    ConfigInfo info = new ConfigInfo();
+    info.defaultProject =
+        Objects.firstNonNull(
+            db.getString(PREFERENCE, username, KEY_DEFAULT_PROJECT),
+            globalCfg.defaultProject);
+    info.linkDecoration =
+        db.getEnum(PREFERENCE, username, KEY_LINK_DECORATION,
+            globalCfg.linkDecoration);
+    if (LinkDecoration.NONE.equals(info.linkDecoration)) {
+      info.linkDecoration = null;
+    }
+    return info;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java
index 3ce1f0b..5ab84bf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java
@@ -16,6 +16,7 @@
 
 import static com.google.gerrit.server.config.ConfigResource.CONFIG_KIND;
 import static com.google.gerrit.server.project.ProjectResource.PROJECT_KIND;
+import static com.google.gerrit.server.account.AccountResource.ACCOUNT_KIND;
 import static com.googlesource.gerrit.plugins.imagare.ImageResource.IMAGE_KIND;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -37,6 +38,8 @@
         child(PROJECT_KIND, "images").to(ImagesCollection.class);
         get(CONFIG_KIND, "config").to(GetConfig.class);
         put(CONFIG_KIND, "config").to(PutConfig.class);
+        get(ACCOUNT_KIND, "preference").to(GetPreference.class);
+        put(ACCOUNT_KIND, "preference").to(PutPreference.class);
       }
     });
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/PutPreference.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/PutPreference.java
new file mode 100644
index 0000000..38cc7f4
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/PutPreference.java
@@ -0,0 +1,114 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.imagare;
+
+import static com.googlesource.gerrit.plugins.imagare.GetPreference.PREFERENCE;
+import static com.googlesource.gerrit.plugins.imagare.GetPreference.KEY_DEFAULT_PROJECT;
+import static com.googlesource.gerrit.plugins.imagare.GetPreference.KEY_LINK_DECORATION;
+
+import com.google.common.base.Strings;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.git.MetaDataUpdate;
+import com.google.gerrit.server.git.ProjectLevelConfig;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import com.googlesource.gerrit.plugins.imagare.PutConfig.Input;
+
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Config;
+
+import java.io.IOException;
+
+public class PutPreference implements RestModifyView<AccountResource, Input> {
+  private final Provider<IdentifiedUser> self;
+  private final ProjectCache projectCache;
+  private final MetaDataUpdate.User metaDataUpdateFactory;
+  private final String pluginName;
+
+  @Inject
+  PutPreference(Provider<IdentifiedUser> self, ProjectCache projectCache,
+      MetaDataUpdate.User metaDataUpdateFactory, @PluginName String pluginName) {
+    this.self = self;
+    this.projectCache = projectCache;
+    this.metaDataUpdateFactory = metaDataUpdateFactory;
+    this.pluginName = pluginName;
+  }
+
+  @Override
+  public Response<String> apply(AccountResource rsrc, Input input)
+      throws AuthException, RepositoryNotFoundException, IOException {
+    if (self.get() != rsrc.getUser()
+        && !self.get().getCapabilities().canAdministrateServer()) {
+      throw new AuthException("not allowed to change preference");
+    }
+    if (input == null) {
+      input = new Input();
+    }
+
+    String username = self.get().getUserName();
+
+    ProjectLevelConfig storage =
+        projectCache.getAllProjects().getConfig(pluginName + ".config");
+    Config db = storage.get();
+    boolean modified = false;
+
+    String defaultProject = db.getString(PREFERENCE, username, KEY_DEFAULT_PROJECT);
+    if (Strings.emptyToNull(input.defaultProject) != null) {
+      if (!input.defaultProject.equals(defaultProject)) {
+        db.setString(PREFERENCE, username, KEY_DEFAULT_PROJECT,
+            input.defaultProject);
+        modified = true;
+      }
+    } else {
+      if (defaultProject != null) {
+        db.unset(PREFERENCE, username, KEY_DEFAULT_PROJECT);
+        modified = true;
+      }
+    }
+
+    if (input.linkDecoration != null) {
+      LinkDecoration linkDecoration =
+          db.getEnum(PREFERENCE, username, KEY_LINK_DECORATION,
+              LinkDecoration.NONE);
+      if (!input.linkDecoration.equals(linkDecoration)) {
+        db.setEnum(PREFERENCE, username, KEY_LINK_DECORATION,
+            input.linkDecoration);
+        modified = true;
+      }
+    } else {
+      if (db.getNames(PREFERENCE, username).contains(KEY_LINK_DECORATION)) {
+        db.unset(PREFERENCE, username, KEY_LINK_DECORATION);
+        modified = true;
+      }
+    }
+
+    if (modified) {
+      MetaDataUpdate md = metaDataUpdateFactory.create(
+          projectCache.getAllProjects().getProject().getNameKey());
+      md.setMessage("Update " + pluginName + " Preferences for '"
+          + username + "'\n");
+      storage.commit(md);
+    }
+
+    return Response.<String> ok("OK");
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareAdminScreen.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareAdminScreen.java
index 1057a56..b6d77f2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareAdminScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareAdminScreen.java
@@ -17,18 +17,8 @@
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.TextBox;
-import com.google.gwt.user.client.ui.VerticalPanel;
 
-public class ImagareAdminScreen extends VerticalPanel {
+public class ImagareAdminScreen extends ImagareConfigScreen {
 
   static class Factory implements Screen.EntryPoint {
     @Override
@@ -38,86 +28,8 @@
     }
   }
 
-  private TextBox projectBox;
-  private ListBox linkDecorationBox;
-  private Button saveButton;
-
   ImagareAdminScreen() {
-    setStyleName("imagare-admin-screen");
-
-    new RestApi("config").id("server").view(Plugin.get().getPluginName(), "config")
-        .get(new AsyncCallback<ConfigInfo>() {
-          @Override
-          public void onSuccess(ConfigInfo info) {
-            display(info);
-          }
-
-          @Override
-          public void onFailure(Throwable caught) {
-            // never invoked
-          }
-        });
-  }
-
-  private void display(ConfigInfo info) {
-    HorizontalPanel p = new HorizontalPanel();
-    p.setStyleName("imagare-label-panel");
-    p.add(new Label("Project:"));
-    projectBox = new TextBox();
-    projectBox.setValue(info.getDefaultProject());
-    p.add(projectBox);
-    add(p);
-
-    p = new HorizontalPanel();
-    p.setStyleName("imagare-label-panel");
-    p.add(new Label("Link Decoration:"));
-    linkDecorationBox = new ListBox();
-    int i = 0;
-    for (LinkDecoration v : LinkDecoration.values()) {
-      linkDecorationBox.addItem(v.name());
-      if (v.equals(info.getLinkDecoration())) {
-        linkDecorationBox.setSelectedIndex(i);
-      }
-      i++;
-    }
-    p.add(linkDecorationBox);
-    add(p);
-
-    HorizontalPanel buttons = new HorizontalPanel();
-    add(buttons);
-
-    saveButton = new Button("Save");
-    saveButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(final ClickEvent event) {
-        doSave();
-      }
-    });
-    buttons.add(saveButton);
-    saveButton.setEnabled(false);
-    OnEditEnabler onEditEnabler = new OnEditEnabler(saveButton, projectBox);
-    onEditEnabler.listenTo(linkDecorationBox);
-
-    projectBox.setFocus(true);
-    saveButton.setEnabled(false);
-  }
-
-  private void doSave() {
-    ConfigInfo in = ConfigInfo.create();
-    in.setDefaultProject(projectBox.getValue());
-    in.setLinkDecoration(linkDecorationBox.getValue(linkDecorationBox.getSelectedIndex()));
-    new RestApi("config").id("server").view(Plugin.get().getPluginName(), "config")
-        .put(in, new AsyncCallback<JavaScriptObject>() {
-
-          @Override
-          public void onSuccess(JavaScriptObject result) {
-            saveButton.setEnabled(false);
-          }
-
-          @Override
-          public void onFailure(Throwable caught) {
-            // never invoked
-          }
-        });
+    super(new RestApi("config").id("server").view(Plugin.get().getPluginName(),
+        "config"));
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java
new file mode 100644
index 0000000..89f8eb8
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java
@@ -0,0 +1,112 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.imagare.client;
+
+import com.google.gerrit.plugin.client.rpc.RestApi;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+public abstract class ImagareConfigScreen extends VerticalPanel {
+  private final RestApi restApi;
+
+  private TextBox projectBox;
+  private ListBox linkDecorationBox;
+  private Button saveButton;
+
+  protected ImagareConfigScreen(RestApi restApi) {
+    this.restApi = restApi;
+    setStyleName("imagare-config-screen");
+    restApi.get(new AsyncCallback<ConfigInfo>() {
+        @Override
+        public void onSuccess(ConfigInfo info) {
+          display(info);
+        }
+
+        @Override
+        public void onFailure(Throwable caught) {
+          // never invoked
+        }
+      });
+  }
+
+  protected void display(ConfigInfo info) {
+    HorizontalPanel p = new HorizontalPanel();
+    p.setStyleName("imagare-label-panel");
+    p.add(new Label("Project:"));
+    projectBox = new TextBox();
+    projectBox.setValue(info.getDefaultProject());
+    p.add(projectBox);
+    add(p);
+
+    p = new HorizontalPanel();
+    p.setStyleName("imagare-label-panel");
+    p.add(new Label("Link Decoration:"));
+    linkDecorationBox = new ListBox();
+    int i = 0;
+    for (LinkDecoration v : LinkDecoration.values()) {
+      linkDecorationBox.addItem(v.name());
+      if (v.equals(info.getLinkDecoration())) {
+        linkDecorationBox.setSelectedIndex(i);
+      }
+      i++;
+    }
+    p.add(linkDecorationBox);
+    add(p);
+
+    HorizontalPanel buttons = new HorizontalPanel();
+    add(buttons);
+
+    saveButton = new Button("Save");
+    saveButton.setStyleName("imagare-save-button");
+    saveButton.addClickHandler(new ClickHandler() {
+      @Override
+      public void onClick(final ClickEvent event) {
+        doSave();
+      }
+    });
+    buttons.add(saveButton);
+    saveButton.setEnabled(false);
+    OnEditEnabler onEditEnabler = new OnEditEnabler(saveButton, projectBox);
+    onEditEnabler.listenTo(linkDecorationBox);
+
+    projectBox.setFocus(true);
+    saveButton.setEnabled(false);
+  }
+
+  private void doSave() {
+    ConfigInfo in = ConfigInfo.create();
+    in.setDefaultProject(projectBox.getValue());
+    in.setLinkDecoration(linkDecorationBox.getValue(linkDecorationBox.getSelectedIndex()));
+    restApi.put(in, new AsyncCallback<JavaScriptObject>() {
+        @Override
+        public void onSuccess(JavaScriptObject result) {
+          saveButton.setEnabled(false);
+        }
+
+        @Override
+        public void onFailure(Throwable caught) {
+          // never invoked
+        }
+      });
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePlugin.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePlugin.java
index 68fca51..f9ad27c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePlugin.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePlugin.java
@@ -25,5 +25,6 @@
   public void onPluginLoad() {
     Plugin.get().screen("upload", new ImageUploadScreen.Factory());
     Plugin.get().screen("admin", new ImagareAdminScreen.Factory());
+    Plugin.get().screen("preferences", new ImagarePreferenceScreen.Factory());
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java
new file mode 100644
index 0000000..a696c59
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.imagare.client;
+
+import com.google.gerrit.plugin.client.Plugin;
+import com.google.gerrit.plugin.client.rpc.RestApi;
+import com.google.gerrit.plugin.client.screen.Screen;
+import com.google.gwt.user.client.ui.InlineHyperlink;
+
+public class ImagarePreferenceScreen extends ImagareConfigScreen {
+
+  static class Factory implements Screen.EntryPoint {
+    @Override
+    public void onLoad(Screen screen) {
+      screen.setPageTitle("Imagare Preferences");
+      screen.show(new ImagarePreferenceScreen());
+    }
+  }
+
+  ImagarePreferenceScreen() {
+    super(new RestApi("accounts").id("self")
+        .view(Plugin.get().getPluginName(), "preference"));
+  }
+
+  @Override
+  protected void display(ConfigInfo info) {
+    super.display(info);
+
+    InlineHyperlink uploadLink =
+        new InlineHyperlink("Upload Image", "/x/"
+            + Plugin.get().getPluginName() + "/upload");
+    add(uploadLink);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImageUploadScreen.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImageUploadScreen.java
index 4af24b7..f7fca27 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImageUploadScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImageUploadScreen.java
@@ -19,6 +19,7 @@
 import com.google.gerrit.plugin.client.screen.Screen;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.InlineHyperlink;
 import com.google.gwt.user.client.ui.Label;
 import com.google.gwt.user.client.ui.TextBox;
 import com.google.gwt.user.client.ui.VerticalPanel;
@@ -51,7 +52,7 @@
     uploadedPanel = new UploadedImagesPanel();
     add(uploadedPanel);
 
-    new RestApi("config").id("server").view(Plugin.get().getPluginName(), "config")
+    new RestApi("accounts").id("self").view(Plugin.get().getPluginName(), "preference")
         .get(new AsyncCallback<ConfigInfo>() {
           @Override
           public void onSuccess(ConfigInfo info) {
@@ -63,5 +64,10 @@
             // never invoked
           }
         });
+
+    InlineHyperlink preferenceLink =
+        new InlineHyperlink("Edit Preferences", "/x/"
+            + Plugin.get().getPluginName() + "/preferences");
+    add(preferenceLink);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/public/imagare.css b/src/main/java/com/googlesource/gerrit/plugins/imagare/public/imagare.css
index 4afd247..411b928 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/public/imagare.css
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/public/imagare.css
@@ -1,5 +1,5 @@
 .imagare-image-upload-screen, .imagare-uploaded-images-panel,
-.imagare-admin-screen {
+.imagare-config-screen {
   width: 100%;
   border-spacing: 0px 5px;
 }
@@ -51,3 +51,7 @@
   max-width: 500px;
   max-height: 500px;
 }
+
+.imagare-save-button {
+  margin-bottom: 10px;
+}
diff --git a/src/main/resources/Documentation/rest-api-accounts.md b/src/main/resources/Documentation/rest-api-accounts.md
new file mode 100644
index 0000000..7ba476d
--- /dev/null
+++ b/src/main/resources/Documentation/rest-api-accounts.md
@@ -0,0 +1,70 @@
+@PLUGIN@ - /accounts/ REST API
+==============================
+
+This page describes the '/accounts/' REST endpoints that are added by
+the @PLUGIN@ plugin.
+
+Please also take note of the general information on the
+[REST API](../../../Documentation/rest-api.html).
+
+<a id="project-endpoints"> @PLUGIN@ Endpoints
+--------------------------------------------
+
+### <a id="get-config"> Get Preferences
+_GET /accounts/[\{account-id\}](../../../Documentation/rest-api-accounts.html#account-id)/@PLUGIN@~preference_
+
+Gets the preferences of a user for the @PLUGIN@ plugin.
+
+#### Request
+
+```
+  GET /accounts/self/@PLUGIN@~preference HTTP/1.0
+```
+
+As response a [ConfigInfo](rest-api-config.html#config-info) entity is
+returned that contains the preferences of a user for the @PLUGIN@
+plugin.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json;charset=UTF-8
+
+  )]}'
+  {
+    "default_project": "All-Images",
+    "link_decoration": "INLINE"
+  }
+```
+
+### <a id="put-config"> Put Preferences
+_PUT /accounts/[\{account-id\}](../../../Documentation/rest-api-accounts.html#account-id)/@PLUGIN@~preference_
+
+Sets the configuration of the @PLUGIN@ plugin.
+
+The new preferences must be specified as a [ConfigInfo](rest-api-config.html#config-info)
+entity in the request body. Not setting a parameter means that the
+parameter is unset and that the global setting for this parameter
+applies again.
+
+#### Request
+
+```
+  PUT /accounts/self/@PLUGIN@~preference HTTP/1.0
+  Content-Type: application/json;charset=UTF-8
+
+  {
+    "default_project": "All-Images"
+  }
+```
+
+SEE ALSO
+--------
+
+* [Account related REST endpoints](../../../Documentation/rest-api-accounts.html)
+
+GERRIT
+------
+Part of [Gerrit Code Review](../../../Documentation/index.html)
diff --git a/src/main/resources/static/imagare.js b/src/main/resources/static/imagare.js
index 0e5a5bf..c23e5db 100644
--- a/src/main/resources/static/imagare.js
+++ b/src/main/resources/static/imagare.js
@@ -14,7 +14,7 @@
 
 Gerrit.install(function(self) {
     function onHistory(t) {
-      Gerrit.get('/config/server/config', function(r) {
+      Gerrit.get('/accounts/self/preference', function(r) {
         if ('TOOLTIP' === r.link_decoration) {
           addTooltips();
         } else if ('INLINE' === r.link_decoration) {