Allow users to register new contributor agreements in Gerrit
The HTML text shown in the body of an agreement is read from a static HTML file in the site path, under "static/", but may also come from any other location on the Internet. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.client;
|
||||
|
||||
import com.google.gerrit.client.account.AccountSettings;
|
||||
import com.google.gerrit.client.account.NewAgreementScreen;
|
||||
import com.google.gerrit.client.admin.AccountGroupScreen;
|
||||
import com.google.gerrit.client.admin.GroupListScreen;
|
||||
import com.google.gerrit.client.changes.AccountDashboardScreen;
|
||||
@@ -39,6 +40,7 @@ public class Link implements HistoryListener {
|
||||
public static final String SETTINGS_WEBIDENT = "settings,web-identities";
|
||||
public static final String SETTINGS_AGREEMENTS = "settings,agreements";
|
||||
public static final String SETTINGS_CONTACT = "settings,contact";
|
||||
public static final String SETTINGS_NEW_AGREEMENT = "settings,new-agreement";
|
||||
|
||||
public static final String MINE = "mine";
|
||||
public static final String MINE_UNCLAIMED = "mine,unclaimed";
|
||||
@@ -108,6 +110,9 @@ public class Link implements HistoryListener {
|
||||
}
|
||||
|
||||
if (SETTINGS.equals(token) || token.startsWith("settings,")) {
|
||||
if (SETTINGS_NEW_AGREEMENT.equals(token)) {
|
||||
return new NewAgreementScreen();
|
||||
}
|
||||
return new AccountSettings(token);
|
||||
}
|
||||
|
||||
|
@@ -58,4 +58,23 @@ public interface AccountConstants extends Constants {
|
||||
String contactFieldPhone();
|
||||
String contactFieldFax();
|
||||
String buttonSaveContact();
|
||||
|
||||
String newAgreement();
|
||||
String agreementStatus();
|
||||
String agreementName();
|
||||
String agreementDescription();
|
||||
String agreementAccepted();
|
||||
String agreementStatus_EXPIRED();
|
||||
String agreementStatus_NEW();
|
||||
String agreementStatus_REJECTED();
|
||||
String agreementStatus_VERIFIED();
|
||||
|
||||
String newAgreementSelectTypeHeading();
|
||||
String newAgreementNoneAvailable();
|
||||
String newAgreementReviewLegalHeading();
|
||||
String newAgreementReviewContactHeading();
|
||||
String newAgreementCompleteHeading();
|
||||
String newAgreementIAGREE();
|
||||
String newAgreementAlreadySubmitted();
|
||||
String buttonSubmitNewAgreement();
|
||||
}
|
||||
|
@@ -39,3 +39,22 @@ contactFieldCountry = Country
|
||||
contactFieldPhone = Phone Number
|
||||
contactFieldFax = Fax Number
|
||||
buttonSaveContact = Save
|
||||
|
||||
newAgreement = New Contributor Agreement
|
||||
agreementStatus = Status
|
||||
agreementName = Name
|
||||
agreementStatus_EXPIRED = Expired
|
||||
agreementStatus_NEW = Pending
|
||||
agreementStatus_REJECTED = Rejected
|
||||
agreementStatus_VERIFIED = Verified
|
||||
agreementDescription = Description
|
||||
agreementAccepted = Accepted
|
||||
|
||||
newAgreementSelectTypeHeading = Select an agreement type:
|
||||
newAgreementNoneAvailable = No contributor agreements are configured.
|
||||
newAgreementReviewLegalHeading = Review the agreement:
|
||||
newAgreementReviewContactHeading = Review your contact information:
|
||||
newAgreementCompleteHeading = Complete the agreement:
|
||||
newAgreementIAGREE = I AGREE
|
||||
newAgreementAlreadySubmitted = Agreement already submitted.
|
||||
buttonSubmitNewAgreement = Submit Agreement
|
||||
|
@@ -18,4 +18,5 @@ import com.google.gwt.i18n.client.Messages;
|
||||
|
||||
public interface AccountMessages extends Messages {
|
||||
String lines(short cnt);
|
||||
String enterIAGREE(String iagree);
|
||||
}
|
||||
|
@@ -1 +1,3 @@
|
||||
lines = {0} lines
|
||||
|
||||
enterIAGREE = (enter {0} in the box to the left)
|
||||
|
@@ -16,6 +16,7 @@ package com.google.gerrit.client.account;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.rpc.SignInRequired;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonService;
|
||||
@@ -41,4 +42,11 @@ public interface AccountService extends RemoteJsonService {
|
||||
@SignInRequired
|
||||
void deleteProjectWatches(Set<AccountProjectWatch.Key> keys,
|
||||
AsyncCallback<VoidResult> callback);
|
||||
|
||||
@SignInRequired
|
||||
void myAgreements(AsyncCallback<AgreementInfo> callback);
|
||||
|
||||
@SignInRequired
|
||||
void enterAgreement(ContributorAgreement.Id id,
|
||||
AsyncCallback<VoidResult> callback);
|
||||
}
|
||||
|
@@ -15,7 +15,9 @@
|
||||
package com.google.gerrit.client.account;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountAgreement;
|
||||
import com.google.gerrit.client.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.client.rpc.BaseServiceImplementation;
|
||||
@@ -128,4 +130,27 @@ public class AccountServiceImpl extends BaseServiceImplementation implements
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void myAgreements(final AsyncCallback<AgreementInfo> callback) {
|
||||
run(callback, new Action<AgreementInfo>() {
|
||||
public AgreementInfo run(final ReviewDb db) throws OrmException {
|
||||
final AgreementInfo i = new AgreementInfo();
|
||||
i.load(RpcUtil.getAccountId(), db);
|
||||
return i;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void enterAgreement(final ContributorAgreement.Id id,
|
||||
final AsyncCallback<VoidResult> callback) {
|
||||
run(callback, new Action<VoidResult>() {
|
||||
public VoidResult run(final ReviewDb db) throws OrmException {
|
||||
final AccountAgreement a =
|
||||
new AccountAgreement(new AccountAgreement.Key(RpcUtil
|
||||
.getAccountId(), id));
|
||||
db.accountAgreements().insert(Collections.singleton(a));
|
||||
return VoidResult.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -25,10 +25,7 @@ import com.google.gerrit.client.ui.LazyTabChild;
|
||||
import com.google.gerrit.client.ui.Screen;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.user.client.History;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.user.client.ui.SourcesTabEvents;
|
||||
import com.google.gwt.user.client.ui.TabListener;
|
||||
import com.google.gwt.user.client.ui.TabPanel;
|
||||
@@ -44,9 +41,7 @@ public class AccountSettings extends AccountScreen {
|
||||
|
||||
private List<String> tabTokens;
|
||||
private TabPanel tabs;
|
||||
|
||||
private PreferencePanel prefsPanel;
|
||||
private Panel agreementsPanel;
|
||||
|
||||
public AccountSettings(final String tabToken) {
|
||||
super(Util.C.accountSettingsHeading());
|
||||
@@ -108,8 +103,6 @@ public class AccountSettings extends AccountScreen {
|
||||
fmt.addStyleName(2, 0, "bottomheader");
|
||||
|
||||
prefsPanel = new PreferencePanel();
|
||||
agreementsPanel = new FlowPanel();
|
||||
agreementsPanel.add(new Label("Not Implemented"));
|
||||
|
||||
tabTokens = new ArrayList<String>();
|
||||
tabs = new TabPanel();
|
||||
@@ -143,7 +136,12 @@ public class AccountSettings extends AccountScreen {
|
||||
}, Util.C.tabWebIdentities());
|
||||
tabTokens.add(Link.SETTINGS_WEBIDENT);
|
||||
|
||||
tabs.add(agreementsPanel, Util.C.tabAgreements());
|
||||
tabs.add(new LazyTabChild<AgreementPanel>() {
|
||||
@Override
|
||||
protected AgreementPanel create() {
|
||||
return new AgreementPanel();
|
||||
}
|
||||
}, Util.C.tabAgreements());
|
||||
tabTokens.add(Link.SETTINGS_AGREEMENTS);
|
||||
|
||||
tabs.addTabListener(new TabListener() {
|
||||
|
@@ -0,0 +1,52 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.account;
|
||||
|
||||
import com.google.gerrit.client.data.AccountInfoCache;
|
||||
import com.google.gerrit.client.data.AccountInfoCacheFactory;
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountAgreement;
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AgreementInfo {
|
||||
protected AccountInfoCache accounts;
|
||||
protected List<AccountAgreement> accepted;
|
||||
protected Map<ContributorAgreement.Id, ContributorAgreement> agreements;
|
||||
|
||||
public AgreementInfo() {
|
||||
}
|
||||
|
||||
public void load(final Account.Id me, final ReviewDb db) throws OrmException {
|
||||
final AccountInfoCacheFactory acc = new AccountInfoCacheFactory(db);
|
||||
|
||||
accepted = db.accountAgreements().byAccount(me).toList();
|
||||
agreements = new HashMap<ContributorAgreement.Id, ContributorAgreement>();
|
||||
for (final AccountAgreement a : accepted) {
|
||||
acc.want(a.getReviewedBy());
|
||||
if (!agreements.containsKey(a.getAgreementId())) {
|
||||
agreements.put(a.getAgreementId(), db.contributorAgreements().get(
|
||||
a.getAgreementId()));
|
||||
}
|
||||
}
|
||||
|
||||
accounts = acc.create();
|
||||
}
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.account;
|
||||
|
||||
import com.google.gerrit.client.FormatUtil;
|
||||
import com.google.gerrit.client.Link;
|
||||
import com.google.gerrit.client.reviewdb.AccountAgreement;
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.FancyFlexTable;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Hyperlink;
|
||||
import com.google.gwt.user.client.ui.SourcesTableEvents;
|
||||
import com.google.gwt.user.client.ui.TableListener;
|
||||
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
||||
|
||||
class AgreementPanel extends Composite {
|
||||
private AgreementTable agreements;
|
||||
|
||||
AgreementPanel() {
|
||||
final FlowPanel body = new FlowPanel();
|
||||
|
||||
agreements = new AgreementTable();
|
||||
body.add(agreements);
|
||||
body.add(new Hyperlink(Util.C.newAgreement(), Link.SETTINGS_NEW_AGREEMENT));
|
||||
|
||||
initWidget(body);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
Util.ACCOUNT_SVC.myAgreements(new GerritCallback<AgreementInfo>() {
|
||||
public void onSuccess(final AgreementInfo result) {
|
||||
agreements.display(result);
|
||||
agreements.finishDisplay(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class AgreementTable extends FancyFlexTable<AccountAgreement> {
|
||||
AgreementTable() {
|
||||
table.setText(0, 1, Util.C.agreementStatus());
|
||||
table.setText(0, 2, Util.C.agreementName());
|
||||
table.setText(0, 3, Util.C.agreementDescription());
|
||||
table.setText(0, 4, Util.C.agreementAccepted());
|
||||
|
||||
table.addTableListener(new TableListener() {
|
||||
public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
|
||||
if (getRowItem(row) != null) {
|
||||
movePointerTo(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final FlexCellFormatter fmt = table.getFlexCellFormatter();
|
||||
for (int c = 1; c <= 4; c++) {
|
||||
fmt.addStyleName(0, c, S_DATA_HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getRowItemKey(final AccountAgreement item) {
|
||||
return item.getKey();
|
||||
}
|
||||
|
||||
void display(final AgreementInfo result) {
|
||||
while (1 < table.getRowCount())
|
||||
table.removeRow(table.getRowCount() - 1);
|
||||
|
||||
for (final AccountAgreement k : result.accepted) {
|
||||
addOne(result, k);
|
||||
}
|
||||
}
|
||||
|
||||
void addOne(final AgreementInfo info, final AccountAgreement k) {
|
||||
final int row = table.getRowCount();
|
||||
table.insertRow(row);
|
||||
|
||||
final ContributorAgreement cla = info.agreements.get(k.getAgreementId());
|
||||
final String statusName;
|
||||
if (cla == null || !cla.isActive()) {
|
||||
statusName = Util.C.agreementStatus_EXPIRED();
|
||||
} else {
|
||||
switch (k.getStatus()) {
|
||||
case NEW:
|
||||
statusName = Util.C.agreementStatus_NEW();
|
||||
break;
|
||||
case REJECTED:
|
||||
statusName = Util.C.agreementStatus_REJECTED();
|
||||
break;
|
||||
case VERIFIED:
|
||||
statusName = Util.C.agreementStatus_VERIFIED();
|
||||
break;
|
||||
default:
|
||||
statusName = k.getStatus().name();
|
||||
}
|
||||
}
|
||||
table.setText(row, 1, statusName);
|
||||
|
||||
if (cla == null) {
|
||||
table.setText(row, 2, "");
|
||||
table.setText(row, 3, "");
|
||||
} else {
|
||||
final String url = cla.getAgreementUrl();
|
||||
if (url != null && url.length() > 0) {
|
||||
final Anchor a = new Anchor(cla.getShortName(), url);
|
||||
a.setTarget("_blank");
|
||||
table.setWidget(row, 2, a);
|
||||
} else {
|
||||
table.setText(row, 2, cla.getShortName());
|
||||
}
|
||||
table.setText(row, 3, cla.getShortDescription());
|
||||
}
|
||||
table.setHTML(row, 4, FormatUtil.mediumFormat(k.getAcceptedOn())
|
||||
+ "<br>\n" + FormatUtil.mediumFormat(k.getReviewedOn()));
|
||||
|
||||
final FlexCellFormatter fmt = table.getFlexCellFormatter();
|
||||
for (int c = 1; c <= 4; c++) {
|
||||
fmt.addStyleName(row, c, S_DATA_CELL);
|
||||
}
|
||||
fmt.addStyleName(row, 4, "C_LAST_UPDATE");
|
||||
|
||||
setRowItem(row, k);
|
||||
}
|
||||
}
|
||||
}
|
@@ -55,6 +55,10 @@ class ContactPanel extends Composite {
|
||||
private TextBox faxTxt;
|
||||
private Button save;
|
||||
|
||||
ContactPanel() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
ContactPanel(final AccountSettings parent) {
|
||||
parentScreen = parent;
|
||||
|
||||
@@ -129,6 +133,10 @@ class ContactPanel extends Composite {
|
||||
initWidget(body);
|
||||
}
|
||||
|
||||
void hideSaveButton() {
|
||||
save.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
@@ -214,7 +222,7 @@ class ContactPanel extends Composite {
|
||||
save.setEnabled(false);
|
||||
}
|
||||
|
||||
private void doSave() {
|
||||
void doSave() {
|
||||
final String newName = nameTxt.getText();
|
||||
final String newEmail;
|
||||
if (emailPick.isEnabled() && emailPick.getSelectedIndex() >= 0) {
|
||||
@@ -238,7 +246,9 @@ class ContactPanel extends Composite {
|
||||
me.setPreferredEmail(newEmail);
|
||||
me.setContactInformation(info);
|
||||
Gerrit.refreshMenuBar();
|
||||
parentScreen.display(me);
|
||||
if (parentScreen != null) {
|
||||
parentScreen.display(me);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@ class ExternalIdPanel extends Composite {
|
||||
}
|
||||
});
|
||||
d.setMode(SignInDialog.Mode.LINK_IDENTIY);
|
||||
d.show();
|
||||
d.center();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,277 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.account;
|
||||
|
||||
import com.google.gerrit.client.ErrorDialog;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.Link;
|
||||
import com.google.gerrit.client.reviewdb.AccountAgreement;
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.AccountScreen;
|
||||
import com.google.gerrit.client.ui.TextSaveButtonListener;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.http.client.Request;
|
||||
import com.google.gwt.http.client.RequestBuilder;
|
||||
import com.google.gwt.http.client.RequestCallback;
|
||||
import com.google.gwt.http.client.RequestException;
|
||||
import com.google.gwt.http.client.Response;
|
||||
import com.google.gwt.user.client.History;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.ClickListener;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.FormPanel;
|
||||
import com.google.gwt.user.client.ui.HTML;
|
||||
import com.google.gwt.user.client.ui.InlineLabel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.user.client.ui.RadioButton;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class NewAgreementScreen extends AccountScreen {
|
||||
private Set<ContributorAgreement.Id> mySigned;
|
||||
private List<ContributorAgreement> available;
|
||||
private ContributorAgreement current;
|
||||
|
||||
private VerticalPanel radios;
|
||||
|
||||
private Panel agreementGroup;
|
||||
private HTML agreementHtml;
|
||||
|
||||
private Panel contactGroup;
|
||||
private ContactPanel contactPanel;
|
||||
|
||||
private Panel finalGroup;
|
||||
private TextBox yesIAgreeBox;
|
||||
private Button submit;
|
||||
|
||||
public NewAgreementScreen() {
|
||||
super(Util.C.newAgreement());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (radios == null) {
|
||||
initUI();
|
||||
}
|
||||
|
||||
mySigned = null;
|
||||
available = null;
|
||||
current = null;
|
||||
|
||||
agreementGroup.setVisible(false);
|
||||
contactGroup.setVisible(false);
|
||||
finalGroup.setVisible(false);
|
||||
super.onLoad();
|
||||
|
||||
Util.ACCOUNT_SVC.myAgreements(new GerritCallback<AgreementInfo>() {
|
||||
public void onSuccess(AgreementInfo result) {
|
||||
if (isAttached()) {
|
||||
mySigned = new HashSet<ContributorAgreement.Id>();
|
||||
for (AccountAgreement a : result.accepted) {
|
||||
mySigned.add(a.getAgreementId());
|
||||
}
|
||||
postRPC();
|
||||
}
|
||||
}
|
||||
});
|
||||
Gerrit.SYSTEM_SVC
|
||||
.contributorAgreements(new GerritCallback<List<ContributorAgreement>>() {
|
||||
public void onSuccess(final List<ContributorAgreement> result) {
|
||||
if (isAttached()) {
|
||||
available = result;
|
||||
postRPC();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initUI() {
|
||||
Label hdr;
|
||||
final FlowPanel formBody = new FlowPanel();
|
||||
radios = new VerticalPanel();
|
||||
formBody.add(radios);
|
||||
|
||||
agreementGroup = new FlowPanel();
|
||||
hdr = new Label(Util.C.newAgreementReviewLegalHeading());
|
||||
hdr.setStyleName("gerrit-SmallHeading");
|
||||
agreementGroup.add(hdr);
|
||||
|
||||
agreementHtml = new HTML();
|
||||
agreementHtml.setStyleName("gerrit-ContributorAgreement-Legal");
|
||||
agreementGroup.add(agreementHtml);
|
||||
formBody.add(agreementGroup);
|
||||
|
||||
contactGroup = new FlowPanel();
|
||||
hdr = new Label(Util.C.newAgreementReviewContactHeading());
|
||||
hdr.setStyleName("gerrit-SmallHeading");
|
||||
contactGroup.add(hdr);
|
||||
formBody.add(contactGroup);
|
||||
|
||||
finalGroup = new VerticalPanel();
|
||||
hdr = new Label(Util.C.newAgreementCompleteHeading());
|
||||
hdr.setStyleName("gerrit-SmallHeading");
|
||||
finalGroup.add(hdr);
|
||||
final FlowPanel fp = new FlowPanel();
|
||||
yesIAgreeBox = new TextBox();
|
||||
yesIAgreeBox.setVisibleLength(Util.C.newAgreementIAGREE().length() + 8);
|
||||
yesIAgreeBox.setMaxLength(Util.C.newAgreementIAGREE().length());
|
||||
fp.add(yesIAgreeBox);
|
||||
fp.add(new InlineLabel(Util.M.enterIAGREE(Util.C.newAgreementIAGREE())));
|
||||
finalGroup.add(fp);
|
||||
submit = new Button(Util.C.buttonSubmitNewAgreement());
|
||||
submit.addClickListener(new ClickListener() {
|
||||
public void onClick(final Widget sender) {
|
||||
doSign();
|
||||
}
|
||||
});
|
||||
finalGroup.add(submit);
|
||||
formBody.add(finalGroup);
|
||||
new TextSaveButtonListener(yesIAgreeBox, submit);
|
||||
|
||||
final FormPanel form = new FormPanel();
|
||||
form.add(formBody);
|
||||
add(form);
|
||||
}
|
||||
|
||||
private void postRPC() {
|
||||
if (mySigned != null && available != null) {
|
||||
display();
|
||||
}
|
||||
}
|
||||
|
||||
private void display() {
|
||||
current = null;
|
||||
agreementGroup.setVisible(false);
|
||||
contactGroup.setVisible(false);
|
||||
finalGroup.setVisible(false);
|
||||
radios.clear();
|
||||
|
||||
final Label hdr;
|
||||
if (available.isEmpty()) {
|
||||
hdr = new Label(Util.C.newAgreementNoneAvailable());
|
||||
} else {
|
||||
hdr = new Label(Util.C.newAgreementSelectTypeHeading());
|
||||
}
|
||||
hdr.setStyleName("gerrit-SmallHeading");
|
||||
radios.add(hdr);
|
||||
|
||||
for (final ContributorAgreement cla : available) {
|
||||
final RadioButton r = new RadioButton("cla_id", cla.getShortName());
|
||||
r.addStyleName("gerrit-ContributorAgreement-Button");
|
||||
radios.add(r);
|
||||
|
||||
if (mySigned.contains(cla.getId())) {
|
||||
r.setEnabled(false);
|
||||
final Label l = new Label(Util.C.newAgreementAlreadySubmitted());
|
||||
l.setStyleName("gerrit-ContributorAgreement-AlreadySubmitted");
|
||||
radios.add(l);
|
||||
} else {
|
||||
r.addClickListener(new ClickListener() {
|
||||
public void onClick(final Widget sender) {
|
||||
showCLA(cla);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (cla.getShortDescription() != null
|
||||
&& !cla.getShortDescription().equals("")) {
|
||||
final Label l = new Label(cla.getShortDescription());
|
||||
l.setStyleName("gerrit-ContributorAgreement-ShortDescription");
|
||||
radios.add(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doSign() {
|
||||
submit.setEnabled(false);
|
||||
|
||||
if (current == null
|
||||
|| !Util.C.newAgreementIAGREE()
|
||||
.equalsIgnoreCase(yesIAgreeBox.getText())) {
|
||||
yesIAgreeBox.setText("");
|
||||
yesIAgreeBox.setFocus(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (contactGroup.isVisible()) {
|
||||
contactPanel.doSave();
|
||||
}
|
||||
Util.ACCOUNT_SVC.enterAgreement(current.getId(),
|
||||
new GerritCallback<VoidResult>() {
|
||||
public void onSuccess(final VoidResult result) {
|
||||
History.newItem(Link.SETTINGS_AGREEMENTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable caught) {
|
||||
yesIAgreeBox.setText("");
|
||||
super.onFailure(caught);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showCLA(final ContributorAgreement cla) {
|
||||
current = cla;
|
||||
String url = cla.getAgreementUrl();
|
||||
if (url != null && url.length() > 0) {
|
||||
agreementGroup.setVisible(true);
|
||||
agreementHtml.setText(Gerrit.C.rpcStatusLoading());
|
||||
if (!url.startsWith("http:") && !url.startsWith("https:")) {
|
||||
url = GWT.getModuleBaseURL() + url;
|
||||
}
|
||||
final RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, url);
|
||||
rb.setCallback(new RequestCallback() {
|
||||
public void onError(Request request, Throwable exception) {
|
||||
new ErrorDialog(exception).center();
|
||||
}
|
||||
|
||||
public void onResponseReceived(Request request, Response response) {
|
||||
final String ct = response.getHeader("Content-Type");
|
||||
if (response.getStatusCode() == 200 && ct != null
|
||||
&& (ct.equals("text/html") || ct.startsWith("text/html;"))) {
|
||||
agreementHtml.setHTML(response.getText());
|
||||
} else {
|
||||
new ErrorDialog(response.getStatusText()).center();
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
rb.send();
|
||||
} catch (RequestException e) {
|
||||
new ErrorDialog(e).show();
|
||||
}
|
||||
} else {
|
||||
agreementGroup.setVisible(false);
|
||||
}
|
||||
|
||||
if (contactPanel == null && cla.isRequireContactInformation()) {
|
||||
contactPanel = new ContactPanel();
|
||||
contactPanel.hideSaveButton();
|
||||
contactGroup.add(contactPanel);
|
||||
}
|
||||
contactGroup.setVisible(cla.isRequireContactInformation());
|
||||
finalGroup.setVisible(true);
|
||||
yesIAgreeBox.setText("");
|
||||
submit.setEnabled(false);
|
||||
}
|
||||
}
|
@@ -14,13 +14,20 @@
|
||||
|
||||
package com.google.gerrit.client.data;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.rpc.SignInRequired;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.AllowCrossSiteRequest;
|
||||
import com.google.gwtjsonrpc.client.HostPageCache;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SystemInfoService extends RemoteJsonService {
|
||||
@AllowCrossSiteRequest
|
||||
@HostPageCache(name = "gerrit_gerritconfig_obj", once = true)
|
||||
void loadGerritConfig(AsyncCallback<GerritConfig> callback);
|
||||
|
||||
@SignInRequired
|
||||
void contributorAgreements(AsyncCallback<List<ContributorAgreement>> callback);
|
||||
}
|
||||
|
@@ -106,6 +106,10 @@ public final class AccountAgreement {
|
||||
status = Status.NEW.getCode();
|
||||
}
|
||||
|
||||
public AccountAgreement.Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public ContributorAgreement.Id getAgreementId() {
|
||||
return key.claId;
|
||||
}
|
||||
|
@@ -68,9 +68,9 @@ public final class ContributorAgreement {
|
||||
@Column(notNull = false)
|
||||
protected String shortDescription;
|
||||
|
||||
/** Text of the agreement, in formatted HTML */
|
||||
@Column(length = Integer.MAX_VALUE)
|
||||
protected String agreementHtml;
|
||||
/** Web address of the agreement documentation. */
|
||||
@Column
|
||||
protected String agreementUrl;
|
||||
|
||||
protected ContributorAgreement() {
|
||||
}
|
||||
@@ -127,11 +127,11 @@ public final class ContributorAgreement {
|
||||
shortDescription = d;
|
||||
}
|
||||
|
||||
public String getAgreementHtml() {
|
||||
return agreementHtml;
|
||||
public String getAgreementUrl() {
|
||||
return agreementUrl;
|
||||
}
|
||||
|
||||
public void setAgreementHtml(final String h) {
|
||||
agreementHtml = h;
|
||||
public void setAgreementUrl(final String h) {
|
||||
agreementUrl = h;
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ public class TextSaveButtonListener extends KeyboardListenerAdapter {
|
||||
|
||||
@Override
|
||||
public void onKeyPress(final Widget sender, final char key, final int mod) {
|
||||
if (mod == 0) {
|
||||
if ((mod & (MODIFIER_CTRL | MODIFIER_ALT | MODIFIER_META)) == 0) {
|
||||
switch (key) {
|
||||
case KEY_UP:
|
||||
case KEY_DOWN:
|
||||
|
@@ -515,5 +515,31 @@
|
||||
margin-top: 10px;
|
||||
padding: 5px 5px 5px 5px;
|
||||
display: table;
|
||||
border: 1px solid #B0BDCC;
|
||||
border: 1px solid #b0bdcc;
|
||||
}
|
||||
|
||||
.gerrit-ContributorAgreement-Button {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gerrit-ContributorAgreement-ShortDescription {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border: 1px solid #b0bdcc;
|
||||
}
|
||||
|
||||
.gerrit-ContributorAgreement-AlreadySubmitted {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
padding: 5px 5px 5px 5px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.gerrit-ContributorAgreement-Legal {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border: 1px solid #b0bdcc;
|
||||
}
|
||||
|
155
appjar/src/main/java/com/google/gerrit/server/StaticServlet.java
Normal file
155
appjar/src/main/java/com/google/gerrit/server/StaticServlet.java
Normal file
@@ -0,0 +1,155 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.server;
|
||||
|
||||
import com.google.gwt.user.server.rpc.RPCServletUtils;
|
||||
import com.google.gwtjsonrpc.server.XsrfException;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
|
||||
import org.spearce.jgit.util.NB;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/** Sends static content from the site 's <code>static/</code> subdirectory. */
|
||||
public class StaticServlet extends HttpServlet {
|
||||
private static final long MAX_AGE = 12 * 60 * 60 * 1000L/* milliseconds */;
|
||||
private static final String CACHE_CTRL =
|
||||
"public, max-age=" + (MAX_AGE / 1000L);
|
||||
|
||||
private static final HashMap<String, String> MIME_TYPES =
|
||||
new HashMap<String, String>();
|
||||
static {
|
||||
MIME_TYPES.put("html", "text/html");
|
||||
MIME_TYPES.put("htm", "text/html");
|
||||
MIME_TYPES.put("js", "application/x-javascript");
|
||||
MIME_TYPES.put("css", "text/css");
|
||||
MIME_TYPES.put("rtf", "text/rtf");
|
||||
MIME_TYPES.put("txt", "text/plain");
|
||||
MIME_TYPES.put("text", "text/plain");
|
||||
MIME_TYPES.put("pdf", "application/pdf");
|
||||
MIME_TYPES.put("jpeg", "image/jpeg");
|
||||
MIME_TYPES.put("jpg", "image/jpeg");
|
||||
MIME_TYPES.put("gif", "image/gif");
|
||||
MIME_TYPES.put("png", "image/png");
|
||||
MIME_TYPES.put("tiff", "image/tiff");
|
||||
MIME_TYPES.put("tif", "image/tiff");
|
||||
MIME_TYPES.put("svg", "image/svg+xml");
|
||||
}
|
||||
|
||||
private static String contentType(final String name) {
|
||||
final int dot = name.lastIndexOf('.');
|
||||
final String ext = 0 < dot ? name.substring(dot + 1) : "";
|
||||
final String type = MIME_TYPES.get(ext);
|
||||
return type != null ? type : "application/octet-stream";
|
||||
}
|
||||
|
||||
private static byte[] readFile(final File p) throws IOException {
|
||||
final FileInputStream in = new FileInputStream(p);
|
||||
try {
|
||||
final byte[] r = new byte[(int) in.getChannel().size()];
|
||||
NB.readFully(in, r, 0, r.length);
|
||||
return r;
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] compress(final byte[] raw) throws IOException {
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
final GZIPOutputStream gz = new GZIPOutputStream(out);
|
||||
gz.write(raw);
|
||||
gz.finish();
|
||||
gz.flush();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
private File staticBase;
|
||||
|
||||
@Override
|
||||
public void init(final ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
|
||||
final GerritServer srv;
|
||||
try {
|
||||
srv = GerritServer.getInstance();
|
||||
} catch (OrmException e) {
|
||||
throw new ServletException("Cannot load GerritServer", e);
|
||||
} catch (XsrfException e) {
|
||||
throw new ServletException("Cannot load GerritServer", e);
|
||||
}
|
||||
|
||||
final File p = srv.getSitePath();
|
||||
staticBase = p != null ? new File(p, "static") : null;
|
||||
}
|
||||
|
||||
private File local(final HttpServletRequest req) {
|
||||
final String name = req.getPathInfo();
|
||||
if (name.startsWith("/") && name.length() > 1 && name.indexOf('/', 1) < 0) {
|
||||
final File p = new File(staticBase, name.substring(1));
|
||||
return p.isFile() ? p : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getLastModified(final HttpServletRequest req) {
|
||||
final File p = local(req);
|
||||
return p != null ? p.lastModified() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(final HttpServletRequest req,
|
||||
final HttpServletResponse rsp) throws IOException {
|
||||
final File p = local(req);
|
||||
if (p == null) {
|
||||
rsp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
final String type = contentType(p.getName());
|
||||
final byte[] tosend;
|
||||
if (!type.equals("application/x-javascript")
|
||||
&& RPCServletUtils.acceptsGzipEncoding(req)) {
|
||||
rsp.setHeader("Content-Encoding", "gzip");
|
||||
tosend = compress(readFile(p));
|
||||
} else {
|
||||
tosend = readFile(p);
|
||||
}
|
||||
|
||||
rsp.setHeader("Cache-Control", CACHE_CTRL);
|
||||
rsp.setDateHeader("Expires", System.currentTimeMillis() + MAX_AGE);
|
||||
rsp.setDateHeader("Last-Modified", p.lastModified());
|
||||
rsp.setContentType(type);
|
||||
rsp.setContentLength(tosend.length);
|
||||
final OutputStream out = rsp.getOutputStream();
|
||||
try {
|
||||
out.write(tosend);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,7 +16,12 @@ package com.google.gerrit.server;
|
||||
|
||||
import com.google.gerrit.client.data.GerritConfig;
|
||||
import com.google.gerrit.client.data.SystemInfoService;
|
||||
import com.google.gerrit.client.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SystemInfoServiceImpl implements SystemInfoService {
|
||||
private final GerritServer server;
|
||||
@@ -28,4 +33,18 @@ public class SystemInfoServiceImpl implements SystemInfoService {
|
||||
public void loadGerritConfig(final AsyncCallback<GerritConfig> callback) {
|
||||
callback.onSuccess(server.getGerritConfig());
|
||||
}
|
||||
|
||||
public void contributorAgreements(
|
||||
final AsyncCallback<List<ContributorAgreement>> callback) {
|
||||
try {
|
||||
final ReviewDb db = server.getDatabase().open();
|
||||
try {
|
||||
callback.onSuccess(db.contributorAgreements().active().toList());
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user