Remove gwtjsonrpc types from new REST API
Only rely on native GWT supplied interfaces like the GWT version of AsyncCallback and StatusCodeException. This allows us to later think about dropping gwtjsonrpc as a project dependency once everything has been converted and no more JSON-RPC 2.0 interfaces exist. Given the size of this change, its better to do it before too many more REST style interfaces are written and depend upon gwtjsonrpc. Change-Id: I7a9f8b73c3612bf7a55a7ec5f82165f8a5cd7107
This commit is contained in:
@@ -17,8 +17,8 @@ package com.google.gerrit.client;
|
|||||||
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_GROUP;
|
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_GROUP;
|
||||||
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
|
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
|
||||||
import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
|
import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
|
||||||
import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
|
|
||||||
import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
|
import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
|
||||||
|
import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
|
||||||
import static com.google.gerrit.common.PageLinks.DASHBOARDS;
|
import static com.google.gerrit.common.PageLinks.DASHBOARDS;
|
||||||
import static com.google.gerrit.common.PageLinks.MINE;
|
import static com.google.gerrit.common.PageLinks.MINE;
|
||||||
import static com.google.gerrit.common.PageLinks.PROJECTS;
|
import static com.google.gerrit.common.PageLinks.PROJECTS;
|
||||||
@@ -74,6 +74,7 @@ import com.google.gerrit.client.dashboards.DashboardInfo;
|
|||||||
import com.google.gerrit.client.dashboards.DashboardList;
|
import com.google.gerrit.client.dashboards.DashboardList;
|
||||||
import com.google.gerrit.client.patches.PatchScreen;
|
import com.google.gerrit.client.patches.PatchScreen;
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gerrit.client.ui.Screen;
|
import com.google.gerrit.client.ui.Screen;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
import com.google.gerrit.common.auth.SignInMode;
|
||||||
@@ -89,7 +90,6 @@ import com.google.gwt.core.client.GWT;
|
|||||||
import com.google.gwt.core.client.RunAsyncCallback;
|
import com.google.gwt.core.client.RunAsyncCallback;
|
||||||
import com.google.gwt.http.client.URL;
|
import com.google.gwt.http.client.URL;
|
||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwtjsonrpc.client.RemoteJsonException;
|
|
||||||
import com.google.gwtorm.client.KeyUtil;
|
import com.google.gwtorm.client.KeyUtil;
|
||||||
|
|
||||||
public class Dispatcher {
|
public class Dispatcher {
|
||||||
@@ -416,9 +416,7 @@ public class Dispatcher {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
if ("default".equals(dashboardId)
|
if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
|
||||||
&& caught instanceof RemoteJsonException
|
|
||||||
&& ((RemoteJsonException) caught).getCode() == 404) {
|
|
||||||
Gerrit.display(PageLinks.toChangeQuery(
|
Gerrit.display(PageLinks.toChangeQuery(
|
||||||
PageLinks.projectQuery(new Project.NameKey(project))));
|
PageLinks.projectQuery(new Project.NameKey(project))));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -14,11 +14,13 @@
|
|||||||
|
|
||||||
package com.google.gerrit.client;
|
package com.google.gerrit.client;
|
||||||
|
|
||||||
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gerrit.client.rpc.RpcConstants;
|
import com.google.gerrit.client.rpc.RpcConstants;
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
import com.google.gwt.event.dom.client.ClickHandler;
|
import com.google.gwt.event.dom.client.ClickHandler;
|
||||||
import com.google.gwt.event.dom.client.KeyPressEvent;
|
import com.google.gwt.event.dom.client.KeyPressEvent;
|
||||||
import com.google.gwt.event.dom.client.KeyPressHandler;
|
import com.google.gwt.event.dom.client.KeyPressHandler;
|
||||||
|
import com.google.gwt.http.client.Response;
|
||||||
import com.google.gwt.user.client.DOM;
|
import com.google.gwt.user.client.DOM;
|
||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwt.user.client.rpc.StatusCodeException;
|
import com.google.gwt.user.client.rpc.StatusCodeException;
|
||||||
@@ -104,35 +106,55 @@ public class ErrorDialog extends PluginSafePopupPanel {
|
|||||||
public ErrorDialog(final Throwable what) {
|
public ErrorDialog(final Throwable what) {
|
||||||
this();
|
this();
|
||||||
|
|
||||||
String cn;
|
String hdr;
|
||||||
if (what instanceof RemoteJsonException) {
|
String msg;
|
||||||
cn = RpcConstants.C.errorRemoteJsonException();
|
|
||||||
|
|
||||||
} else if (what instanceof StatusCodeException) {
|
if (what instanceof StatusCodeException) {
|
||||||
cn = RpcConstants.C.errorServerUnavailable();
|
StatusCodeException sc = (StatusCodeException) what;
|
||||||
|
if (RestApi.isExpected(sc.getStatusCode())) {
|
||||||
|
hdr = null;
|
||||||
|
msg = sc.getEncodedResponse();
|
||||||
|
} else if (sc.getStatusCode() == Response.SC_INTERNAL_SERVER_ERROR) {
|
||||||
|
hdr = null;
|
||||||
|
msg = what.getMessage();
|
||||||
|
} else {
|
||||||
|
hdr = RpcConstants.C.errorServerUnavailable();
|
||||||
|
msg = what.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (what instanceof RemoteJsonException) {
|
||||||
|
// TODO Remove RemoteJsonException from Gerrit sources.
|
||||||
|
hdr = RpcConstants.C.errorRemoteJsonException();
|
||||||
|
msg = what.getMessage();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cn = what.getClass().getName();
|
// TODO Fix callers of ErrorDialog to stop passing random types.
|
||||||
if (cn.startsWith("java.lang.")) {
|
hdr = what.getClass().getName();
|
||||||
cn = cn.substring("java.lang.".length());
|
if (hdr.startsWith("java.lang.")) {
|
||||||
} else if (cn.startsWith("com.google.gerrit.")) {
|
hdr = hdr.substring("java.lang.".length());
|
||||||
cn = cn.substring(cn.lastIndexOf('.') + 1);
|
} else if (hdr.startsWith("com.google.gerrit.")) {
|
||||||
|
hdr = hdr.substring(hdr.lastIndexOf('.') + 1);
|
||||||
}
|
}
|
||||||
if (cn.endsWith("Exception")) {
|
if (hdr.endsWith("Exception")) {
|
||||||
cn = cn.substring(0, cn.length() - "Exception".length());
|
hdr = hdr.substring(0, hdr.length() - "Exception".length());
|
||||||
} else if (cn.endsWith("Error")) {
|
} else if (hdr.endsWith("Error")) {
|
||||||
cn = cn.substring(0, cn.length() - "Error".length());
|
hdr = hdr.substring(0, hdr.length() - "Error".length());
|
||||||
}
|
}
|
||||||
|
msg = what.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Label r = new Label(cn);
|
if (hdr != null) {
|
||||||
|
final Label r = new Label(hdr);
|
||||||
r.setStyleName(Gerrit.RESOURCES.css().errorDialogErrorType());
|
r.setStyleName(Gerrit.RESOURCES.css().errorDialogErrorType());
|
||||||
body.add(r);
|
body.add(r);
|
||||||
|
}
|
||||||
|
|
||||||
final Label m = new Label(what.getMessage());
|
if (msg != null) {
|
||||||
DOM.setStyleAttribute(m.getElement(),"whiteSpace","pre");
|
final Label m = new Label(msg);
|
||||||
|
DOM.setStyleAttribute(m.getElement(), "whiteSpace", "pre");
|
||||||
body.add(m);
|
body.add(m);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setText(final String t) {
|
public void setText(final String t) {
|
||||||
text.setText(t);
|
text.setText(t);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ linkIdentityDialogTitle = Code Review - Link Identity
|
|||||||
registerDialogTitle = Code Review - Register New Account
|
registerDialogTitle = Code Review - Register New Account
|
||||||
loginTypeUnsupported = Sign in is not available.
|
loginTypeUnsupported = Sign in is not available.
|
||||||
|
|
||||||
errorDialogTitle = Application Error
|
errorDialogTitle = Code Review - Error
|
||||||
errorDialogContinue = Continue
|
errorDialogContinue = Continue
|
||||||
|
|
||||||
confirmationDialogOk = OK
|
confirmationDialogOk = OK
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ package com.google.gerrit.client.account;
|
|||||||
|
|
||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/** Capabilities the caller has from {@code /accounts/self/capabilities}. */
|
/** Capabilities the caller has from {@code /accounts/self/capabilities}. */
|
||||||
public class AccountCapabilities extends JavaScriptObject {
|
public class AccountCapabilities extends JavaScriptObject {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ package com.google.gerrit.client.changes;
|
|||||||
import com.google.gerrit.client.rpc.NativeString;
|
import com.google.gerrit.client.rpc.NativeString;
|
||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of static methods which work on the Gerrit REST API for specific
|
* A collection of static methods which work on the Gerrit REST API for specific
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ package com.google.gerrit.client.changes;
|
|||||||
|
|
||||||
import static com.google.gerrit.client.FormatUtil.mediumFormat;
|
import static com.google.gerrit.client.FormatUtil.mediumFormat;
|
||||||
|
|
||||||
import com.google.gerrit.client.ErrorDialog;
|
|
||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
import com.google.gerrit.client.ui.AccountLink;
|
import com.google.gerrit.client.ui.AccountLink;
|
||||||
import com.google.gerrit.client.ui.CommentedActionDialog;
|
|
||||||
import com.google.gerrit.client.ui.BranchLink;
|
import com.google.gerrit.client.ui.BranchLink;
|
||||||
|
import com.google.gerrit.client.ui.CommentedActionDialog;
|
||||||
import com.google.gerrit.client.ui.ProjectLink;
|
import com.google.gerrit.client.ui.ProjectLink;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.common.data.AccountInfoCache;
|
import com.google.gerrit.common.data.AccountInfoCache;
|
||||||
@@ -39,7 +39,6 @@ import com.google.gwt.user.client.ui.InlineLabel;
|
|||||||
import com.google.gwt.user.client.ui.TextBox;
|
import com.google.gwt.user.client.ui.TextBox;
|
||||||
import com.google.gwt.user.client.ui.Widget;
|
import com.google.gwt.user.client.ui.Widget;
|
||||||
import com.google.gwtexpui.clippy.client.CopyableLabel;
|
import com.google.gwtexpui.clippy.client.CopyableLabel;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
|
|
||||||
public class ChangeInfoBlock extends Composite {
|
public class ChangeInfoBlock extends Composite {
|
||||||
private static final int R_CHANGE_ID = 0;
|
private static final int R_CHANGE_ID = 0;
|
||||||
@@ -187,7 +186,7 @@ public class ChangeInfoBlock extends Composite {
|
|||||||
public void onSend() {
|
public void onSend() {
|
||||||
String topic = newTopic.getText();
|
String topic = newTopic.getText();
|
||||||
ChangeApi.topic(change.getId().get(), topic, getMessageText(),
|
ChangeApi.topic(change.getId().get(), topic, getMessageText(),
|
||||||
new AsyncCallback<String>() {
|
new GerritCallback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(String result) {
|
public void onSuccess(String result) {
|
||||||
sent = true;
|
sent = true;
|
||||||
@@ -198,7 +197,7 @@ public class ChangeInfoBlock extends Composite {
|
|||||||
@Override
|
@Override
|
||||||
public void onFailure(final Throwable caught) {
|
public void onFailure(final Throwable caught) {
|
||||||
enableButtons(true);
|
enableButtons(true);
|
||||||
new ErrorDialog(caught.getMessage()).center();
|
super.onFailure(caught);
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ package com.google.gerrit.client.changes;
|
|||||||
import com.google.gerrit.client.rpc.NativeList;
|
import com.google.gerrit.client.rpc.NativeList;
|
||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gerrit.common.changes.ListChangesOption;
|
import com.google.gerrit.common.changes.ListChangesOption;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
import com.google.gwtorm.client.KeyUtil;
|
import com.google.gwtorm.client.KeyUtil;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import com.google.gerrit.client.ui.Screen;
|
|||||||
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
|
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
|
||||||
import com.google.gwt.event.dom.client.KeyPressEvent;
|
import com.google.gwt.event.dom.client.KeyPressEvent;
|
||||||
import com.google.gwt.user.client.History;
|
import com.google.gwt.user.client.History;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||||
import com.google.gwtexpui.globalkey.client.KeyCommand;
|
import com.google.gwtexpui.globalkey.client.KeyCommand;
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
package com.google.gerrit.client.changes;
|
package com.google.gerrit.client.changes;
|
||||||
|
|
||||||
import com.google.gerrit.client.Dispatcher;
|
import com.google.gerrit.client.Dispatcher;
|
||||||
import com.google.gerrit.client.ErrorDialog;
|
|
||||||
import com.google.gerrit.client.FormatUtil;
|
import com.google.gerrit.client.FormatUtil;
|
||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
import com.google.gerrit.client.GitwebLink;
|
import com.google.gerrit.client.GitwebLink;
|
||||||
@@ -49,7 +48,6 @@ import com.google.gwt.user.client.ui.Grid;
|
|||||||
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
|
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
|
||||||
import com.google.gwt.user.client.ui.InlineLabel;
|
import com.google.gwt.user.client.ui.InlineLabel;
|
||||||
import com.google.gwt.user.client.ui.Panel;
|
import com.google.gwt.user.client.ui.Panel;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
import com.google.gwtjsonrpc.common.VoidResult;
|
import com.google.gwtjsonrpc.common.VoidResult;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -355,7 +353,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
|
|||||||
@Override
|
@Override
|
||||||
public void onSend() {
|
public void onSend() {
|
||||||
ChangeApi.revert(changeDetail.getChange().getChangeId(),
|
ChangeApi.revert(changeDetail.getChange().getChangeId(),
|
||||||
getMessageText(), new AsyncCallback<ChangeInfo>() {
|
getMessageText(), new GerritCallback<ChangeInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ChangeInfo result) {
|
public void onSuccess(ChangeInfo result) {
|
||||||
sent = true;
|
sent = true;
|
||||||
@@ -367,7 +365,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
|
|||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
enableButtons(true);
|
enableButtons(true);
|
||||||
new ErrorDialog(caught.getMessage()).center();
|
super.onFailure(caught);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -395,7 +393,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
|
|||||||
// REST APIs, we can use createCallback() rather than providing
|
// REST APIs, we can use createCallback() rather than providing
|
||||||
// them directly.
|
// them directly.
|
||||||
ChangeApi.abandon(changeDetail.getChange().getChangeId(),
|
ChangeApi.abandon(changeDetail.getChange().getChangeId(),
|
||||||
getMessageText(), new AsyncCallback<ChangeInfo>() {
|
getMessageText(), new GerritCallback<ChangeInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ChangeInfo result) {
|
public void onSuccess(ChangeInfo result) {
|
||||||
sent = true;
|
sent = true;
|
||||||
@@ -407,7 +405,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
|
|||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
enableButtons(true);
|
enableButtons(true);
|
||||||
new ErrorDialog(caught.getMessage()).center();
|
super.onFailure(caught);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -456,7 +454,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
|
|||||||
@Override
|
@Override
|
||||||
public void onSend() {
|
public void onSend() {
|
||||||
ChangeApi.restore(changeDetail.getChange().getChangeId(),
|
ChangeApi.restore(changeDetail.getChange().getChangeId(),
|
||||||
getMessageText(), new AsyncCallback<ChangeInfo>() {
|
getMessageText(), new GerritCallback<ChangeInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ChangeInfo result) {
|
public void onSuccess(ChangeInfo result) {
|
||||||
sent = true;
|
sent = true;
|
||||||
@@ -468,7 +466,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
|
|||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
enableButtons(true);
|
enableButtons(true);
|
||||||
new ErrorDialog(caught.getMessage()).center();
|
super.onFailure(caught);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import com.google.gerrit.client.rpc.GerritCallback;
|
|||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.RevId;
|
import com.google.gerrit.reviewdb.client.RevId;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
import com.google.gwtorm.client.KeyUtil;
|
import com.google.gwtorm.client.KeyUtil;
|
||||||
|
|
||||||
public class QueryScreen extends PagedSingleListScreen implements
|
public class QueryScreen extends PagedSingleListScreen implements
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import com.google.gerrit.client.rpc.NativeList;
|
|||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
import com.google.gwt.http.client.URL;
|
import com.google.gwt.http.client.URL;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/** Project dashboards from {@code /projects/<name>/dashboards/}. */
|
/** Project dashboards from {@code /projects/<name>/dashboards/}. */
|
||||||
public class DashboardList extends NativeList<DashboardInfo> {
|
public class DashboardList extends NativeList<DashboardInfo> {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ package com.google.gerrit.client.plugins;
|
|||||||
|
|
||||||
import com.google.gerrit.client.rpc.NativeMap;
|
import com.google.gerrit.client.rpc.NativeMap;
|
||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/** Plugins available from {@code /plugins/}. */
|
/** Plugins available from {@code /plugins/}. */
|
||||||
public class PluginMap extends NativeMap<PluginInfo> {
|
public class PluginMap extends NativeMap<PluginInfo> {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ package com.google.gerrit.client.projects;
|
|||||||
|
|
||||||
import com.google.gerrit.client.rpc.NativeMap;
|
import com.google.gerrit.client.rpc.NativeMap;
|
||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/** Projects available from {@code /projects/}. */
|
/** Projects available from {@code /projects/}. */
|
||||||
public class ProjectMap extends NativeMap<ProjectInfo> {
|
public class ProjectMap extends NativeMap<ProjectInfo> {
|
||||||
|
|||||||
@@ -24,14 +24,17 @@ import com.google.gerrit.common.errors.NoSuchEntityException;
|
|||||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||||
import com.google.gerrit.common.errors.NotSignedInException;
|
import com.google.gerrit.common.errors.NotSignedInException;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.http.client.Response;
|
||||||
import com.google.gwt.user.client.rpc.InvocationException;
|
import com.google.gwt.user.client.rpc.InvocationException;
|
||||||
|
import com.google.gwt.user.client.rpc.StatusCodeException;
|
||||||
import com.google.gwtjsonrpc.client.RemoteJsonException;
|
import com.google.gwtjsonrpc.client.RemoteJsonException;
|
||||||
import com.google.gwtjsonrpc.client.ServerUnavailableException;
|
import com.google.gwtjsonrpc.client.ServerUnavailableException;
|
||||||
import com.google.gwtjsonrpc.common.JsonConstants;
|
import com.google.gwtjsonrpc.common.JsonConstants;
|
||||||
|
|
||||||
/** Abstract callback handling generic error conditions automatically */
|
/** Abstract callback handling generic error conditions automatically */
|
||||||
public abstract class GerritCallback<T> implements AsyncCallback<T> {
|
public abstract class GerritCallback<T> implements
|
||||||
|
com.google.gwtjsonrpc.common.AsyncCallback<T>,
|
||||||
|
com.google.gwt.user.client.rpc.AsyncCallback<T> {
|
||||||
public void onFailure(final Throwable caught) {
|
public void onFailure(final Throwable caught) {
|
||||||
if (isNotSignedIn(caught) || isInvalidXSRF(caught)) {
|
if (isNotSignedIn(caught) || isInvalidXSRF(caught)) {
|
||||||
new NotSignedInDialog().center();
|
new NotSignedInDialog().center();
|
||||||
@@ -76,14 +79,16 @@ public abstract class GerritCallback<T> implements AsyncCallback<T> {
|
|||||||
&& caught.getMessage().equals(JsonConstants.ERROR_INVALID_XSRF);
|
&& caught.getMessage().equals(JsonConstants.ERROR_INVALID_XSRF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNotSignedIn(final Throwable caught) {
|
private static boolean isNotSignedIn(Throwable caught) {
|
||||||
return caught instanceof RemoteJsonException
|
return RestApi.isNotSignedIn(caught)
|
||||||
&& caught.getMessage().equals(NotSignedInException.MESSAGE);
|
|| (caught instanceof RemoteJsonException
|
||||||
|
&& caught.getMessage().equals(NotSignedInException.MESSAGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isNoSuchEntity(final Throwable caught) {
|
protected static boolean isNoSuchEntity(Throwable caught) {
|
||||||
return caught instanceof RemoteJsonException
|
return RestApi.isNotFound(caught)
|
||||||
&& caught.getMessage().equals(NoSuchEntityException.MESSAGE);
|
|| (caught instanceof RemoteJsonException
|
||||||
|
&& caught.getMessage().equals(NoSuchEntityException.MESSAGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isInactiveAccount(final Throwable caught) {
|
protected static boolean isInactiveAccount(final Throwable caught) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
package com.google.gerrit.client.rpc;
|
package com.google.gerrit.client.rpc;
|
||||||
|
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
package com.google.gerrit.client.rpc;
|
package com.google.gerrit.client.rpc;
|
||||||
|
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/** Wraps a String that was returned from a JSON API. */
|
/** Wraps a String that was returned from a JSON API. */
|
||||||
public final class NativeString extends JavaScriptObject {
|
public final class NativeString extends JavaScriptObject {
|
||||||
|
|||||||
@@ -34,14 +34,16 @@ import com.google.gwt.json.client.JSONException;
|
|||||||
import com.google.gwt.json.client.JSONObject;
|
import com.google.gwt.json.client.JSONObject;
|
||||||
import com.google.gwt.json.client.JSONParser;
|
import com.google.gwt.json.client.JSONParser;
|
||||||
import com.google.gwt.json.client.JSONValue;
|
import com.google.gwt.json.client.JSONValue;
|
||||||
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
import com.google.gwt.user.client.rpc.StatusCodeException;
|
import com.google.gwt.user.client.rpc.StatusCodeException;
|
||||||
import com.google.gwtjsonrpc.client.RemoteJsonException;
|
|
||||||
import com.google.gwtjsonrpc.client.ServerUnavailableException;
|
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
import com.google.gwtjsonrpc.common.JsonConstants;
|
|
||||||
|
|
||||||
/** Makes a REST API call to the server. */
|
/** Makes a REST API call to the server. */
|
||||||
public class RestApi {
|
public class RestApi {
|
||||||
|
private static final int SC_UNAVAILABLE = 2;
|
||||||
|
private static final int SC_TRANSPORT = 3;
|
||||||
|
private static final String JSON_TYPE = "application/json";
|
||||||
|
private static final String TEXT_TYPE = "text/plain";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON content body prefix that prevents XSSI.
|
* Expected JSON content body prefix that prevents XSSI.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -53,8 +55,53 @@ public class RestApi {
|
|||||||
*/
|
*/
|
||||||
private static final String JSON_MAGIC = ")]}'\n";
|
private static final String JSON_MAGIC = ")]}'\n";
|
||||||
|
|
||||||
private class MyRequestCallback<T extends JavaScriptObject> implements
|
/** True if err is a StatusCodeException reporting Not Found. */
|
||||||
RequestCallback {
|
public static boolean isNotFound(Throwable err) {
|
||||||
|
return isStatus(err, Response.SC_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** True if err is describing a user that is currently anonymous. */
|
||||||
|
public static boolean isNotSignedIn(Throwable err) {
|
||||||
|
if (err instanceof StatusCodeException) {
|
||||||
|
StatusCodeException sce = (StatusCodeException) err;
|
||||||
|
if (sce.getStatusCode() == Response.SC_UNAUTHORIZED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return sce.getStatusCode() == Response.SC_FORBIDDEN
|
||||||
|
&& (sce.getEncodedResponse().equals("Authentication required")
|
||||||
|
|| sce.getEncodedResponse().startsWith("Must be signed-in"));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** True if err is a StatusCodeException with a specific HTTP code. */
|
||||||
|
public static boolean isStatus(Throwable err, int status) {
|
||||||
|
return err instanceof StatusCodeException
|
||||||
|
&& ((StatusCodeException) err).getStatusCode() == status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Is the Gerrit Code Review server likely to return this status? */
|
||||||
|
public static boolean isExpected(int statusCode) {
|
||||||
|
switch (statusCode) {
|
||||||
|
case SC_UNAVAILABLE:
|
||||||
|
case 400: // Bad Request
|
||||||
|
case 401: // Unauthorized
|
||||||
|
case 403: // Forbidden
|
||||||
|
case 404: // Not Found
|
||||||
|
case 405: // Method Not Allowed
|
||||||
|
case 409: // Conflict
|
||||||
|
case 429: // Too Many Requests (RFC 6585)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Assume any other code is not expected. These may be
|
||||||
|
// local proxy server errors outside of our control.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyRequestCallback<T extends JavaScriptObject>
|
||||||
|
implements RequestCallback {
|
||||||
private final AsyncCallback<T> cb;
|
private final AsyncCallback<T> cb;
|
||||||
|
|
||||||
MyRequestCallback(AsyncCallback<T> cb) {
|
MyRequestCallback(AsyncCallback<T> cb) {
|
||||||
@@ -84,21 +131,15 @@ public class RestApi {
|
|||||||
msg = res.getStatusText();
|
msg = res.getStatusText();
|
||||||
}
|
}
|
||||||
|
|
||||||
Throwable error;
|
|
||||||
if (400 <= status && status < 600) {
|
|
||||||
error = new RemoteJsonException(msg, status, null);
|
|
||||||
} else {
|
|
||||||
error = new StatusCodeException(status, res.getStatusText());
|
|
||||||
}
|
|
||||||
RpcStatus.INSTANCE.onRpcComplete();
|
RpcStatus.INSTANCE.onRpcComplete();
|
||||||
cb.onFailure(error);
|
cb.onFailure(new StatusCodeException(status, msg));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isJsonBody(res)) {
|
if (!isJsonBody(res)) {
|
||||||
RpcStatus.INSTANCE.onRpcComplete();
|
RpcStatus.INSTANCE.onRpcComplete();
|
||||||
cb.onFailure(new RemoteJsonException("Expected "
|
cb.onFailure(new StatusCodeException(200, "Expected "
|
||||||
+ JsonConstants.JSON_TYPE + "; received Content-Type: "
|
+ JSON_TYPE + "; received Content-Type: "
|
||||||
+ res.getHeader("Content-Type")));
|
+ res.getHeader("Content-Type")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -108,7 +149,8 @@ public class RestApi {
|
|||||||
data = cast(parseJson(res));
|
data = cast(parseJson(res));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
RpcStatus.INSTANCE.onRpcComplete();
|
RpcStatus.INSTANCE.onRpcComplete();
|
||||||
cb.onFailure(new RemoteJsonException("Invalid JSON: " + e.getMessage()));
|
cb.onFailure(new StatusCodeException(200,
|
||||||
|
"Invalid JSON: " + e.getMessage()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +162,11 @@ public class RestApi {
|
|||||||
public void onError(Request req, Throwable err) {
|
public void onError(Request req, Throwable err) {
|
||||||
RpcStatus.INSTANCE.onRpcComplete();
|
RpcStatus.INSTANCE.onRpcComplete();
|
||||||
if (err.getMessage().contains("XmlHttpRequest.status")) {
|
if (err.getMessage().contains("XmlHttpRequest.status")) {
|
||||||
cb.onFailure(new ServerUnavailableException());
|
cb.onFailure(new StatusCodeException(
|
||||||
|
SC_UNAVAILABLE,
|
||||||
|
RpcConstants.C.errorServerUnavailable()));
|
||||||
} else {
|
} else {
|
||||||
cb.onFailure(err);
|
cb.onFailure(new StatusCodeException(SC_TRANSPORT, err.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,13 +241,13 @@ public class RestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RestApi data(JSONObject obj) {
|
public RestApi data(JSONObject obj) {
|
||||||
contentType = JsonConstants.JSON_REQ_CT;
|
contentType = JSON_TYPE + "; charset=utf-8";
|
||||||
contentData = obj.toString();
|
contentData = obj.toString();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestApi data(String data) {
|
public RestApi data(String data) {
|
||||||
contentType = "text/plain; charset=utf-8";
|
contentType = TEXT_TYPE + "; charset=utf-8";
|
||||||
contentData = data;
|
contentData = data;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -229,28 +273,28 @@ public class RestApi {
|
|||||||
Method method,
|
Method method,
|
||||||
final AsyncCallback<T> cb) {
|
final AsyncCallback<T> cb) {
|
||||||
RequestBuilder req = new RequestBuilder(method, url.toString());
|
RequestBuilder req = new RequestBuilder(method, url.toString());
|
||||||
req.setHeader("Accept", JsonConstants.JSON_TYPE);
|
req.setHeader("Accept", JSON_TYPE);
|
||||||
if (Gerrit.getAuthorization() != null) {
|
if (Gerrit.getAuthorization() != null) {
|
||||||
req.setHeader("Authorization", Gerrit.getAuthorization());
|
req.setHeader("Authorization", Gerrit.getAuthorization());
|
||||||
}
|
}
|
||||||
if (contentData != null) {
|
if (contentData != null) {
|
||||||
req.setHeader("Content-Type", contentType);
|
req.setHeader("Content-Type", contentType);
|
||||||
}
|
}
|
||||||
|
MyRequestCallback<T> httpCallback = new MyRequestCallback<T>(cb);
|
||||||
try {
|
try {
|
||||||
RpcStatus.INSTANCE.onRpcStart();
|
RpcStatus.INSTANCE.onRpcStart();
|
||||||
req.sendRequest(contentData, new MyRequestCallback<T>(cb));
|
req.sendRequest(contentData, httpCallback);
|
||||||
} catch (RequestException e) {
|
} catch (RequestException e) {
|
||||||
RpcStatus.INSTANCE.onRpcComplete();
|
httpCallback.onError(null, e);
|
||||||
cb.onFailure(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isJsonBody(Response res) {
|
private static boolean isJsonBody(Response res) {
|
||||||
return isContentType(res, JsonConstants.JSON_TYPE);
|
return isContentType(res, JSON_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTextBody(Response res) {
|
private static boolean isTextBody(Response res) {
|
||||||
return isContentType(res, "text/plain");
|
return isContentType(res, TEXT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isContentType(Response res, String want) {
|
private static boolean isContentType(Response res, String want) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.client.rpc;
|
package com.google.gerrit.client.rpc;
|
||||||
|
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
|
||||||
/** Transforms a value and passes it on to another callback. */
|
/** Transforms a value and passes it on to another callback. */
|
||||||
public abstract class TransformCallback<I, O> implements AsyncCallback<I>{
|
public abstract class TransformCallback<I, O> implements AsyncCallback<I>{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.httpd.restapi;
|
package com.google.gerrit.httpd.restapi;
|
||||||
|
|
||||||
|
import static com.google.common.base.Charsets.UTF_8;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
|
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
|
||||||
@@ -35,6 +36,7 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.net.HttpHeaders;
|
||||||
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
import com.google.gerrit.extensions.restapi.AcceptsCreate;
|
import com.google.gerrit.extensions.restapi.AcceptsCreate;
|
||||||
@@ -68,8 +70,6 @@ import com.google.gson.JsonParseException;
|
|||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonToken;
|
import com.google.gson.stream.JsonToken;
|
||||||
import com.google.gwtjsonrpc.common.JsonConstants;
|
|
||||||
import com.google.gwtjsonrpc.server.RPCServletUtils;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.util.Providers;
|
import com.google.inject.util.Providers;
|
||||||
@@ -86,7 +86,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -110,9 +109,8 @@ public class RestApiServlet extends HttpServlet {
|
|||||||
.getLogger(RestApiServlet.class);
|
.getLogger(RestApiServlet.class);
|
||||||
|
|
||||||
/** MIME type used for a JSON response body. */
|
/** MIME type used for a JSON response body. */
|
||||||
private static final String JSON_TYPE = JsonConstants.JSON_TYPE;
|
private static final String JSON_TYPE = "application/json";
|
||||||
private static final String FORM_TYPE = "application/x-www-form-urlencoded";
|
private static final String FORM_TYPE = "application/x-www-form-urlencoded";
|
||||||
private static final String UTF_8 = "UTF-8";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Garbage prefix inserted before JSON output to prevent XSSI.
|
* Garbage prefix inserted before JSON output to prevent XSSI.
|
||||||
@@ -126,11 +124,7 @@ public class RestApiServlet extends HttpServlet {
|
|||||||
private static final byte[] JSON_MAGIC;
|
private static final byte[] JSON_MAGIC;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
|
||||||
JSON_MAGIC = ")]}'\n".getBytes(UTF_8);
|
JSON_MAGIC = ")]}'\n".getBytes(UTF_8);
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new RuntimeException("UTF-8 not supported", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Globals {
|
public static class Globals {
|
||||||
@@ -419,7 +413,7 @@ public class RestApiServlet extends HttpServlet {
|
|||||||
public void writeTo(OutputStream os) throws IOException {
|
public void writeTo(OutputStream os) throws IOException {
|
||||||
buf.writeTo(os, null);
|
buf.writeTo(os, null);
|
||||||
}
|
}
|
||||||
}.setContentType(JSON_TYPE).setCharacterEncoding(UTF_8));
|
}.setContentType(JSON_TYPE).setCharacterEncoding(UTF_8.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final FieldNamingPolicy NAMING =
|
private static final FieldNamingPolicy NAMING =
|
||||||
@@ -676,11 +670,15 @@ public class RestApiServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean acceptsJson(HttpServletRequest req) {
|
private static boolean acceptsJson(HttpServletRequest req) {
|
||||||
return req != null && isType(JSON_TYPE, req.getHeader("Accept"));
|
return req != null && isType(JSON_TYPE, req.getHeader(HttpHeaders.ACCEPT));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean acceptsGzip(HttpServletRequest req) {
|
private static boolean acceptsGzip(HttpServletRequest req) {
|
||||||
return req != null && RPCServletUtils.acceptsGzipEncoding(req);
|
if (req != null) {
|
||||||
|
String accepts = req.getHeader(HttpHeaders.ACCEPT_ENCODING);
|
||||||
|
return accepts != null && accepts.indexOf("gzip") != -1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isType(String expect, String given) {
|
private static boolean isType(String expect, String given) {
|
||||||
|
|||||||
Reference in New Issue
Block a user