/* * Copyright 2011-2017 Amazon Technologies, 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://aws.amazon.com/apache2.0 * * This file 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.amazonaws.eclipse.codecommit.explorer; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.layout.TreeColumnLayout; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreePathContentProvider; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.part.EditorPart; import com.amazonaws.eclipse.codecommit.CodeCommitPlugin; import com.amazonaws.eclipse.codecommit.CodeCommitUtil; import com.amazonaws.eclipse.codecommit.explorer.CodeCommitActionProvider.CloneRepositoryAction; import com.amazonaws.eclipse.core.AwsToolkitCore; import com.amazonaws.services.codecommit.AWSCodeCommit; import com.amazonaws.services.codecommit.model.Commit; import com.amazonaws.services.codecommit.model.GetBranchRequest; import com.amazonaws.services.codecommit.model.GetCommitRequest; import com.amazonaws.services.codecommit.model.GetRepositoryRequest; import com.amazonaws.services.codecommit.model.ListBranchesRequest; import com.amazonaws.services.codecommit.model.RepositoryMetadata; import com.amazonaws.util.StringUtils; import static com.amazonaws.eclipse.codecommit.CodeCommitUtil.nonNullString; public class RepositoryEditor extends EditorPart { public final static String ID = "com.amazonaws.eclipse.codecommit.explorer.RepositoryEditor"; private static final int DEFAUT_COMMIT_HISTORY_COUNT = 10; private RepositoryEditorInput repositoryEditorInput; private AWSCodeCommit client; private Text lastModifiedDateText; private Text repositoryDescriptionText; private Text cloneUrlHttpText; private Text cloneUrlSSHText; private Combo branchCombo; private TreeViewer viewer; @Override public void doSave(IProgressMonitor monitor) {} @Override public void doSaveAs() {} @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { setSite(site); setInput(input); repositoryEditorInput = (RepositoryEditorInput) input; client = AwsToolkitCore.getClientFactory(repositoryEditorInput.getAccountId()) .getCodeCommitClientByEndpoint(repositoryEditorInput.getRegionEndpoint()); setPartName(input.getName()); } @Override public boolean isDirty() { return false; } @Override public boolean isSaveAsAllowed() { return false; } @Override public void createPartControl(Composite parent) { FormToolkit toolkit = new FormToolkit(Display.getDefault()); ScrolledForm form = new ScrolledForm(parent, SWT.V_SCROLL); toolkit.decorateFormHeading(form.getForm()); form.setExpandHorizontal(true); form.setExpandVertical(true); form.setBackground(toolkit.getColors().getBackground()); form.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); form.setFont(JFaceResources.getHeaderFont()); form.setText(repositoryEditorInput.getName()); form.setImage(CodeCommitPlugin.getDefault().getImageRegistry().get(CodeCommitPlugin.IMG_REPOSITORY)); form.getBody().setLayout(new GridLayout()); createRepositorySummary(form.getBody(), toolkit); createCommitHistory(form.getBody(), toolkit); form.getToolBarManager().add(new RefreshAction()); form.getToolBarManager().update(true); } private void createRepositorySummary(Composite parent, FormToolkit toolkit) { final String repositoryName = repositoryEditorInput.getRepository().getRepositoryName(); final Composite composite = toolkit.createComposite(parent); composite.setLayout(new GridLayout(2, false)); composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); toolkit.createLabel(composite, "Last Modified Date: "); lastModifiedDateText = toolkit.createText(composite, "", SWT.READ_ONLY); lastModifiedDateText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); toolkit.createLabel(composite, "Repository Description: "); repositoryDescriptionText = toolkit.createText(composite, "", SWT.READ_ONLY | SWT.H_SCROLL | SWT.FLAT); repositoryDescriptionText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); toolkit.createLabel(composite, "Clone URL Https: "); cloneUrlHttpText = toolkit.createText(composite, "", SWT.READ_ONLY); cloneUrlHttpText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); toolkit.createLabel(composite, "Clone URL SSH: "); cloneUrlSSHText = toolkit.createText(composite, "", SWT.READ_ONLY); cloneUrlSSHText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Button checkoutButton = toolkit.createButton(composite, "Check out", SWT.PUSH); checkoutButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { CloneRepositoryAction.executeCloneAction(client, repositoryName); } }); new LoadSummaryDataThread().start(); } private void createCommitHistory(Composite parent, FormToolkit toolkit) { Composite commitHistoryComposite = toolkit.createComposite(parent); commitHistoryComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); commitHistoryComposite.setLayout(new GridLayout()); Composite headerComposite = toolkit.createComposite(commitHistoryComposite); headerComposite.setLayout(new GridLayout(2, true)); headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Label label = toolkit.createLabel(headerComposite, "Commit History for Branch:"); label.setFont(JFaceResources.getHeaderFont()); label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); ComboViewer branchComboViewer = new ComboViewer(headerComposite, SWT.READ_ONLY | SWT.DROP_DOWN); branchCombo = branchComboViewer.getCombo(); branchCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); branchCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { onBranchSelected(); } }); Composite composite = toolkit.createComposite(commitHistoryComposite); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); TreeColumnLayout tableColumnLayout = new TreeColumnLayout(); composite.setLayout(tableColumnLayout); CommitContentProvider contentProvider = new CommitContentProvider(); CommitLabelProvider labelProvider = new CommitLabelProvider(); viewer = new TreeViewer(composite, SWT.BORDER | SWT.MULTI); viewer.getTree().setLinesVisible(true); viewer.getTree().setHeaderVisible(true); viewer.setLabelProvider(labelProvider); viewer.setContentProvider(contentProvider); createColumns(tableColumnLayout, viewer.getTree()); viewer.setInput(new Object()); new LoadBranchesThread().start(); } private void createColumns(TreeColumnLayout columnLayout, Tree tree) { createColumn(tree, columnLayout, "Commit ID"); createColumn(tree, columnLayout, "Message"); createColumn(tree, columnLayout, "Committer"); createColumn(tree, columnLayout, "Date"); } private TreeColumn createColumn(Tree tree, TreeColumnLayout columnLayout, String text) { TreeColumn column = new TreeColumn(tree, SWT.NONE); column.setText(text); column.setMoveable(true); columnLayout.setColumnData(column, new ColumnWeightData(30)); return column; } @Override public void setFocus() {} private class LoadSummaryDataThread extends Thread { @Override public void run() { final String repositoryName = repositoryEditorInput.getName(); final RepositoryMetadata metadata = client.getRepository( new GetRepositoryRequest() .withRepositoryName(repositoryName)) .getRepositoryMetadata(); Display.getDefault().asyncExec(new Runnable() { public void run() { lastModifiedDateText.setText(metadata.getLastModifiedDate().toString()); repositoryDescriptionText.setText(nonNullString(metadata.getRepositoryDescription())); cloneUrlHttpText.setText(metadata.getCloneUrlHttp()); cloneUrlSSHText.setText(metadata.getCloneUrlSsh()); } }); } } private class LoadBranchesThread extends Thread { @Override public void run() { Display.getDefault().asyncExec(new Runnable() { public void run() { branchCombo.removeAll(); List<String> branches = client.listBranches(new ListBranchesRequest() .withRepositoryName(repositoryEditorInput.getRepository().getRepositoryName())) .getBranches(); if (!branches.isEmpty()) { for (String branch : branches) { branchCombo.add(branch); } String defautBranch = client.getRepository(new GetRepositoryRequest() .withRepositoryName(repositoryEditorInput.getRepository().getRepositoryName())) .getRepositoryMetadata().getDefaultBranch(); branchCombo.select(branchCombo.indexOf(defautBranch)); } new LoadCommitHistoryThread().start(); } }); } } private class LoadCommitHistoryThread extends Thread { @Override public void run() { Display.getDefault().asyncExec(new Runnable() { public void run() { String repositoryName = repositoryEditorInput.getRepository().getRepositoryName(); String currentBranch = branchCombo.getText(); List<CommitRow> row = new ArrayList<CommitRow>(); if (!StringUtils.isNullOrEmpty(currentBranch)) { String commitId = client.getBranch(new GetBranchRequest() .withRepositoryName(repositoryName) .withBranchName(currentBranch)) .getBranch().getCommitId(); int count = DEFAUT_COMMIT_HISTORY_COUNT; while (count-- > 0 && commitId != null) { Commit commit = client.getCommit(new GetCommitRequest() .withRepositoryName(repositoryName) .withCommitId(commitId)) .getCommit(); row.add(new CommitRow(commitId, commit)); List<String> parent = commit.getParents(); commitId = parent != null && !parent.isEmpty() ? parent.get(0) : null; } } viewer.setInput(row); } }); } } private class RefreshAction extends Action { public RefreshAction() { this.setText("Refresh"); this.setToolTipText("Refresh CodeCommit Repository"); this.setImageDescriptor(AwsToolkitCore.getDefault().getImageRegistry().getDescriptor( AwsToolkitCore.IMAGE_REFRESH)); } @Override public void run() { new LoadSummaryDataThread().start(); new LoadBranchesThread().start(); } } private final class CommitContentProvider implements ITreePathContentProvider { private CommitRow[] commits; public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (newInput instanceof List) { commits = ((List<CommitRow>)newInput).toArray(new CommitRow[0]); } else { commits = new CommitRow[0]; } } public void dispose() { } public Object[] getChildren(TreePath arg0) { return null; } public Object[] getElements(Object arg0) { return commits; } public TreePath[] getParents(Object arg0) { return null; } public boolean hasChildren(TreePath arg0) { return false; } } private final class CommitLabelProvider implements ITableLabelProvider { public void addListener(ILabelProviderListener arg0) { } public void dispose() { } public boolean isLabelProperty(Object arg0, String arg1) { return false; } public void removeListener(ILabelProviderListener arg0) { } public Image getColumnImage(Object arg0, int arg1) { return null; } public String getColumnText(Object obj, int column) { if (obj instanceof CommitRow == false) return ""; CommitRow message = (CommitRow) obj; switch (column) { case 0: return message.getCommitId(); case 1: return message.getCommit().getMessage(); case 2: return message.getCommit().getCommitter().getName(); case 3: return CodeCommitUtil.codeCommitTimeToHumanReadible(message.getCommit().getCommitter().getDate()); } return ""; } } // POJO class acting as the row data model for the commit history table. private final class CommitRow { private final String commitId; private final Commit commit; public CommitRow(String commitId, Commit commit) { this.commitId = commitId; this.commit = commit; } public String getCommitId() { return commitId; } public Commit getCommit() { return commit; } } private void onBranchSelected() { new LoadCommitHistoryThread().start(); } }