blob: 9ba4deff84cb035ce48089d6c04ef2fc5ed929ff [file] [log] [blame]
// Copyright (C) 2008 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.google.gerrit.client;
import com.google.gerrit.client.data.GerritConfig;
import com.google.gerrit.client.data.SystemInfoService;
import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.client.reviewdb.SystemConfig;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.LinkMenuBar;
import com.google.gerrit.client.ui.LinkMenuItem;
import com.google.gerrit.client.ui.Screen;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwtexpui.user.client.UserAgent;
import com.google.gwtjsonrpc.client.JsonUtil;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
public class Gerrit implements EntryPoint {
/**
* Name of the Cookie our authentication data is stored in.
* <p>
* If this cookie has a value we assume we are signed in.
*
* @see #isSignedIn()
*/
public static final String ACCOUNT_COOKIE = "GerritAccount";
public static final GerritConstants C = GWT.create(GerritConstants.class);
public static final GerritMessages M = GWT.create(GerritMessages.class);
public static final GerritIcons ICONS = GWT.create(GerritIcons.class);
public static final SystemInfoService SYSTEM_SVC;
private static String myVersion;
private static Account myAccount;
private static final ArrayList<SignedInListener> signedInListeners =
new ArrayList<SignedInListener>();
private static LinkMenuBar menuBar;
private static RootPanel siteHeader;
private static RootPanel siteFooter;
private static RootPanel body;
private static Screen currentScreen;
private static final LinkedHashMap<Object, Screen> priorScreens =
new LinkedHashMap<Object, Screen>(10, 0.75f, true) {
@Override
protected boolean removeEldestEntry(final Entry<Object, Screen> eldest) {
return 3 <= size();
}
};
static {
SYSTEM_SVC = GWT.create(SystemInfoService.class);
JsonUtil.bind(SYSTEM_SVC, "rpc/SystemInfoService");
}
public static void display(final String historyToken, final boolean go) {
History.newItem(historyToken, go);
if (!go && historyHooks != null) {
dispatchHistoryHooks(historyToken);
}
}
public static void display(final String historyToken, final Screen view) {
History.newItem(historyToken, false);
display(view);
if (historyHooks != null) {
dispatchHistoryHooks(historyToken);
}
}
public static void display(final Screen view) {
if (view.isRequiresSignIn() && !isSignedIn()) {
doSignIn(new AsyncCallback<Object>() {
public void onSuccess(final Object result) {
display(view);
}
public void onFailure(final Throwable caught) {
}
});
return;
}
if (currentScreen != null) {
body.remove(currentScreen);
final Object sct = currentScreen.getScreenCacheToken();
if (sct != null) {
priorScreens.put(sct, currentScreen);
}
}
final Screen p = priorScreens.get(view.getScreenCacheToken());
currentScreen = p != null ? p.recycleThis(view) : view;
body.add(currentScreen);
}
public static void uncache(final Screen view) {
priorScreens.remove(view.getScreenCacheToken());
}
/** @return the currently signed in user's account data; null if no account */
public static Account getUserAccount() {
return myAccount;
}
/** @return true if the user is currently authenticated */
public static boolean isSignedIn() {
return getUserAccount() != null;
}
/**
* Sign the user into the application.
*
* @param callback optional; if sign in is successful the onSuccess method
* will be called.
*/
public static void doSignIn(final AsyncCallback<?> callback) {
new SignInDialog(callback).center();
}
/** Sign the user out of the application (and discard the cookies). */
public static void doSignOut() {
myAccount = null;
Cookies.removeCookie(ACCOUNT_COOKIE);
for (final SignedInListener l : signedInListeners) {
l.onSignOut();
}
refreshMenuBar();
if (currentScreen != null) {
currentScreen.onSignOut();
}
}
/** Add a listener to monitor sign-in status. */
public static void addSignedInListener(final SignedInListener l) {
if (!signedInListeners.contains(l)) {
signedInListeners.add(l);
}
}
/** Remove a previously added sign in listener. */
public static void removeSignedInListener(final SignedInListener l) {
signedInListeners.remove(l);
}
public void onModuleLoad() {
UserAgent.assertNotInIFrame();
initHistoryHooks();
populateBottomMenu();
final RootPanel topMenu = RootPanel.get("gerrit_topmenu");
menuBar = new LinkMenuBar();
topMenu.add(menuBar);
siteHeader = RootPanel.get("gerrit_header");
body = RootPanel.get("gerrit_body");
siteFooter = RootPanel.get("gerrit_footer");
JsonUtil.addRpcStatusListener(new RpcStatus(topMenu));
SYSTEM_SVC.loadGerritConfig(new GerritCallback<GerritConfig>() {
public void onSuccess(final GerritConfig result) {
Common.setGerritConfig(result);
onModuleLoad2();
}
});
}
private static ArrayList<JavaScriptObject> historyHooks;
private static native void initHistoryHooks()
/*-{ $wnd['gerrit_addHistoryHook'] = function(h) { @com.google.gerrit.client.Gerrit::addHistoryHook(Lcom/google/gwt/core/client/JavaScriptObject;)(h); }; }-*/;
static void addHistoryHook(final JavaScriptObject hook) {
if (historyHooks == null) {
historyHooks = new ArrayList<JavaScriptObject>();
History.addHistoryListener(new HistoryListener() {
public void onHistoryChanged(final String historyToken) {
dispatchHistoryHooks(historyToken);
}
});
}
historyHooks.add(hook);
}
private static native void callHistoryHook(JavaScriptObject hook, String url)
/*-{ hook(url); }-*/;
private static void dispatchHistoryHooks(final String historyToken) {
final String url = Window.Location.getPath() + "#" + historyToken;
for (final JavaScriptObject hook : historyHooks) {
callHistoryHook(hook, url);
}
}
private static void populateBottomMenu() {
final RootPanel btmmenu = RootPanel.get("gerrit_btmmenu");
final String vs = getVersion();
final HTML version = new HTML(M.poweredBy(vs));
version.setStyleName("gerrit-version");
btmmenu.add(version);
}
/** @return version number of the Gerrit application software */
public static String getVersion() {
if (myVersion == null) {
if (GWT.isScript()) {
final GerritVersion v = GWT.create(GerritVersion.class);
myVersion = v.version();
} else {
myVersion = "dev";
}
}
return myVersion;
}
private void onModuleLoad2() {
if (Cookies.getCookie(ACCOUNT_COOKIE) != null
|| Common.getGerritConfig().getLoginType() == SystemConfig.LoginType.HTTP) {
// If the user is likely to already be signed into their account,
// load the account data and update the UI with that.
//
com.google.gerrit.client.account.Util.ACCOUNT_SVC
.myAccount(new AsyncCallback<Account>() {
public void onSuccess(final Account result) {
if (result != null) {
postSignIn(result, null);
} else {
Cookies.removeCookie(ACCOUNT_COOKIE);
refreshMenuBar();
}
showInitialScreen();
}
public void onFailure(final Throwable caught) {
if (!GWT.isScript() && !GerritCallback.isNotSignedIn(caught)) {
GWT.log("Unexpected failure from validating account", caught);
}
Cookies.removeCookie(ACCOUNT_COOKIE);
refreshMenuBar();
showInitialScreen();
}
});
} else {
refreshMenuBar();
showInitialScreen();
}
}
private void showInitialScreen() {
final RootPanel sg = RootPanel.get("gerrit_startinggerrit");
sg.getElement().getParentElement().removeChild(sg.getElement());
RootPanel.detachNow(sg);
History.addHistoryListener(new Link());
if ("".equals(History.getToken())) {
if (isSignedIn()) {
History.newItem(Link.MINE);
} else {
History.newItem(Link.ALL_OPEN);
}
} else {
History.fireCurrentHistoryState();
}
}
/** Hook from {@link SignInDialog} to let us know to refresh the UI. */
static void postSignIn(final Account acct, final AsyncCallback<?> ac) {
myAccount = acct;
refreshMenuBar();
for (final SignedInListener l : signedInListeners) {
l.onSignIn();
}
if (currentScreen != null) {
currentScreen.onSignIn();
}
if (ac != null) {
ac.onSuccess(null);
}
}
public static void refreshMenuBar() {
menuBar.clearItems();
final boolean signedIn = isSignedIn();
MenuBar m;
m = new MenuBar(true);
addLink(m, C.menuAllOpen(), Link.ALL_OPEN);
addLink(m, C.menuAllMerged(), Link.ALL_MERGED);
addLink(m, C.menuAllAbandoned(), Link.ALL_ABANDONED);
menuBar.addItem(C.menuAll(), m);
if (signedIn) {
m = new MenuBar(true);
addLink(m, C.menuMyChanges(), Link.MINE);
addLink(m, C.menyMyDrafts(), Link.MINE_DRAFTS);
addLink(m, C.menuMyStarredChanges(), Link.MINE_STARRED);
addLink(m, C.menuSettings(), Link.SETTINGS);
menuBar.addItem(C.menuMine(), m);
}
if (signedIn) {
m = new MenuBar(true);
addLink(m, C.menuGroups(), Link.ADMIN_GROUPS);
addLink(m, C.menuProjects(), Link.ADMIN_PROJECTS);
menuBar.addItem(C.menuAdmin(), m);
}
menuBar.lastInGroup();
menuBar.addGlue();
if (signedIn) {
whoAmI();
menuBar.addItem(new LinkMenuItem(C.menuSettings(), Link.SETTINGS));
switch (Common.getGerritConfig().getLoginType()) {
case HTTP:
break;
case OPENID:
default:
menuBar.addItem(C.menuSignOut(), new Command() {
public void execute() {
doSignOut();
}
});
break;
}
} else {
switch (Common.getGerritConfig().getLoginType()) {
case HTTP:
break;
case OPENID:
default:
menuBar.addItem(C.menuSignIn(), new Command() {
public void execute() {
doSignIn(null);
}
});
break;
}
}
menuBar.lastInGroup();
final boolean view = myAccount == null || myAccount.isShowSiteHeader();
if (siteHeader != null) {
siteHeader.setVisible(view);
}
if (siteFooter != null) {
siteFooter.setVisible(view);
}
}
private static void whoAmI() {
final String name = FormatUtil.nameEmail(getUserAccount());
final MenuItem me = menuBar.addItem(name, (Command) null);
me.removeStyleName("gwt-MenuItem");
me.addStyleName("gerrit-MenuBarUserName");
}
private static void addLink(final MenuBar m, final String text,
final String historyToken) {
m.addItem(new LinkMenuItem(text, historyToken));
}
}