Java tutorial
/******************************************************************************* * Copyright (c) 2011 Robert Munteanu and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Robert Munteanu - initial API and implementation *******************************************************************************/ package org.review_board.ereviewboard.subclipse.internal.wizards; import java.lang.reflect.InvocationTargetException; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.TasksUi; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; import org.eclipse.team.core.RepositoryProvider; import org.review_board.ereviewboard.core.ReviewboardClientManager; import org.review_board.ereviewboard.core.ReviewboardCorePlugin; import org.review_board.ereviewboard.core.client.ReviewboardClient; import org.review_board.ereviewboard.core.exception.ReviewboardException; import org.review_board.ereviewboard.core.model.Repository; import org.review_board.ereviewboard.core.model.RepositoryType; import org.review_board.ereviewboard.core.model.ReviewRequest; import org.review_board.ereviewboard.subclipse.Activator; import org.review_board.ereviewboard.subclipse.TraceLocation; import org.tigris.subversion.subclipse.core.*; import org.tigris.subversion.subclipse.core.resources.LocalResourceStatus; import org.tigris.subversion.subclipse.core.resources.SVNWorkspaceRoot; import org.tigris.subversion.svnclientadapter.ISVNClientAdapter; import org.tigris.subversion.svnclientadapter.ISVNInfo; import org.tigris.subversion.svnclientadapter.SVNClientException; /** * The <tt>DetectLocalChangesPage</tt> shows the local changes * * <p>It also allows selection of the resources to be included in the review request.</p> * * @author Robert Munteanu * */ class DetectLocalChangesPage extends WizardPage { private final IProject _project; private Table _table; private final Set<ChangedFile> _selectedFiles = new HashSet<ChangedFile>(); private ISVNRepositoryLocation svnRepositoryLocation; private Repository _reviewBoardRepository; private TaskRepository _taskRepository; private Label _foundRbRepositoryLabel; private Label _foundSvnRepositoryLabel; private final CreateReviewRequestWizardContext _context; private boolean _alreadyPopulated; private final ReviewRequest _reviewRequest; public DetectLocalChangesPage(IProject project, CreateReviewRequestWizardContext context, ReviewRequest reviewRequest) { super("Detect local changes", "Detect local changes", null); setMessage( "Select the changes to submit for review. The ReviewBoard instance and the SVN repository have been auto-detected.", IMessageProvider.INFORMATION); _project = project; _context = context; _reviewRequest = reviewRequest; } public void createControl(Composite parent) { Composite layout = new Composite(parent, SWT.NONE); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(layout); Label rbRepositoryLabel = new Label(layout, SWT.NONE); rbRepositoryLabel.setText("Reviewboard repository :"); _foundRbRepositoryLabel = new Label(layout, SWT.NONE); _foundRbRepositoryLabel.setText("Unknown"); Label svnRepositoryLabel = new Label(layout, SWT.NONE); svnRepositoryLabel.setText("SVN repository :"); _foundSvnRepositoryLabel = new Label(layout, SWT.NONE); _foundSvnRepositoryLabel.setText("Unknown"); if (_reviewRequest != null) { Label reviewRequestLabel = new Label(layout, SWT.NONE); reviewRequestLabel.setText("Review request :"); Label reviewRequestName = new Label(layout, SWT.NONE); reviewRequestName.setText(_reviewRequest.getSummary()); } _table = new Table(layout, SWT.BORDER | SWT.V_SCROLL | SWT.CHECK); _table.setLinesVisible(true); _table.setHeaderVisible(true); GridDataFactory.fillDefaults().span(2, 1).hint(500, 300).grab(true, true).applyTo(_table); TableColumn includeColumn = new TableColumn(_table, SWT.NONE); includeColumn.setText("Include"); TableColumn typeColumn = new TableColumn(_table, SWT.NONE); typeColumn.setText("Change type"); TableColumn fileColumn = new TableColumn(_table, SWT.NONE); fileColumn.setText("File"); _table.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { if (event.detail == SWT.CHECK) { ChangedFile eventData = (ChangedFile) event.item.getData(); if (_selectedFiles.contains(eventData)) _selectedFiles.remove(eventData); else _selectedFiles.add(eventData); Activator.getDefault().trace(TraceLocation.MAIN, "Number of selected files is " + _selectedFiles.size()); if (_selectedFiles.isEmpty()) setErrorMessage("Please select at least one change to submit for review."); else setErrorMessage(null); getContainer().updateButtons(); } } }); setControl(layout); } @Override public void setVisible(boolean visible) { super.setVisible(visible); if (visible) populate(); } private void populate() { if (_alreadyPopulated) return; try { getWizard().getContainer().run(false, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { SVNTeamProvider svnProvider = (SVNTeamProvider) RepositoryProvider.getProvider(_project, SVNProviderPlugin.getTypeId()); Assert.isNotNull(svnProvider, "No " + SVNTeamProvider.class.getSimpleName() + " for " + _project); ISVNLocalResource projectSvnResource = SVNWorkspaceRoot.getSVNResourceFor(_project); String localRepositoryUuid; try { ISVNInfo info = projectSvnResource.getRepository().getSVNClient() .getInfo(projectSvnResource.getUrl()); localRepositoryUuid = info.getUuid(); } catch (SVNException e1) { throw new InvocationTargetException(e1, "Unable to find uuid for repository at" + projectSvnResource.getRepository().getUrl()); } catch (SVNClientException e1) { throw new InvocationTargetException(e1, "Unable to find uuid for repository at" + projectSvnResource.getRepository().getUrl()); } if (localRepositoryUuid == null) { setErrorMessage("No uuid found for local SVN repository, unable to continue"); return; } ReviewboardClientManager clientManager = ReviewboardCorePlugin.getDefault().getConnector() .getClientManager(); ReviewboardClient rbClient = null; Repository reviewBoardRepository = null; TaskRepository taskRepository = null; setSvnRepositoryLocation(projectSvnResource.getRepository()); Activator.getDefault().trace(TraceLocation.MAIN, "Local repository is " + getSvnRepositoryLocation().getRepositoryRoot().toString() + ", uuid is " + localRepositoryUuid); List<String> clientUrls = clientManager.getAllClientUrl(); if (clientUrls.isEmpty()) { setMessage( "No Reviewboard repositories are defined. Please add one using the Task Repositories view.", IMessageProvider.WARNING); return; } boolean hasSvnRepos = false; for (String clientUrl : clientUrls) { TaskRepository repositoryCandidate = TasksUi.getRepositoryManager() .getRepository(ReviewboardCorePlugin.REPOSITORY_KIND, clientUrl); if (repositoryCandidate == null) { Activator.getDefault().log(IStatus.WARNING, "No repository for clientUrl " + clientUrl + " skipping."); continue; } Activator.getDefault().trace(TraceLocation.MAIN, "Checking repository candidate " + repositoryCandidate.getRepositoryLabel()); ReviewboardClient client = clientManager.getClient(repositoryCandidate); Activator.getDefault().trace(TraceLocation.MAIN, "Got reviewboardClient " + client); try { client.updateRepositoryData(false, monitor); } catch (ReviewboardException e) { throw new InvocationTargetException(e, "Failed updating the repository data for " + repositoryCandidate.getRepositoryLabel() + " : " + e.getMessage()); } catch (RuntimeException e) { throw new InvocationTargetException(e, "Failed updating the repository data for " + repositoryCandidate.getRepositoryLabel() + " : " + e.getMessage()); } Activator.getDefault().trace(TraceLocation.MAIN, "Refreshed repository data , got " + client.getClientData().getRepositories().size() + " repositories."); for (Repository repository : client.getClientData().getRepositories()) { Activator.getDefault().trace(TraceLocation.MAIN, "Considering repository of type " + repository.getTool() + " and path " + repository.getPath()); if (repository.getTool() != RepositoryType.Subversion) continue; hasSvnRepos = true; if (localRepositoryUuid .equals(repository.getRepositoryInfo().get(Repository.PN_UUID))) { reviewBoardRepository = repository; taskRepository = repositoryCandidate; rbClient = client; break; } } } if (!hasSvnRepos) { setMessage( "No Subversion repositories are defined in the configured ReviewBoard servers. Please add the correspoding repositories to ReviewBoard."); return; } setReviewboardClient(rbClient); setReviewboardRepository(reviewBoardRepository); setTaskRepository(taskRepository); if (taskRepository != null && reviewBoardRepository != null) { _foundRbRepositoryLabel.setText(taskRepository.getRepositoryLabel()); _foundRbRepositoryLabel.setToolTipText(taskRepository.getUrl()); _foundSvnRepositoryLabel.setText(reviewBoardRepository.getName()); _foundSvnRepositoryLabel.setToolTipText(reviewBoardRepository.getPath()); } else { setErrorMessage("No SVN repository defined in ReviewBoard for path " + getSvnRepositoryLocation().getRepositoryRoot() + ". Please ensure that the repository URL from Eclipse matches the one from ReviewBoard."); return; } try { LocalResourceStatus status = projectSvnResource.getStatus(); Activator.getDefault().trace(TraceLocation.MAIN, "SVN repository status is " + status); Assert.isNotNull(status, "No status for resource " + projectSvnResource); ISVNClientAdapter svnClient = getSvnRepositoryLocation().getSVNClient(); ChangedFileFinder changedFileFinder = new ChangedFileFinder(projectSvnResource, svnClient); List<ChangedFile> changedFiles = changedFileFinder.findChangedFiles(); Activator.getDefault().trace(TraceLocation.MAIN, "Found " + changedFiles.size() + " changed files."); for (ChangedFile changedFile : changedFiles) { TableItem item = new TableItem(_table, SWT.NONE); item.setData(changedFile); item.setText(0, ""); item.setText(1, changedFile.getStatusKind().toString()); item.setText(2, changedFile.getPathRelativeToProject()); item.setChecked(true); _selectedFiles.add(changedFile); } for (int i = 0; i < _table.getColumnCount(); i++) _table.getColumn(i).pack(); if (_selectedFiles.isEmpty()) { setErrorMessage( "No changes found in the repository which can be used to create a diff."); return; } } catch (SVNException e) { throw new InvocationTargetException(e); } catch (SVNClientException e) { throw new InvocationTargetException(e); } } }); } catch (InvocationTargetException e) { setErrorMessage(e.getMessage()); } catch (InterruptedException e) { setErrorMessage(e.getMessage()); } catch (RuntimeException e) { setErrorMessage(getErrorMessage()); Activator.getDefault().log(IStatus.ERROR, e.getMessage(), e); } finally { _alreadyPopulated = true; } } @Override public boolean isPageComplete() { return super.isPageComplete() && getTaskRepository() != null && getReviewBoardRepository() != null && getSelectedFiles().size() > 0; } public Set<ChangedFile> getSelectedFiles() { return _selectedFiles; } public ISVNRepositoryLocation getSvnRepositoryLocation() { return svnRepositoryLocation; } public Repository getReviewBoardRepository() { return _reviewBoardRepository; } public TaskRepository getTaskRepository() { return _taskRepository; } void setSvnRepositoryLocation(ISVNRepositoryLocation svnRepositoryLocation) { this.svnRepositoryLocation = svnRepositoryLocation; } void setReviewboardClient(ReviewboardClient rbClient) { _context.setReviewboardClient(rbClient); } void setReviewboardRepository(Repository reviewBoardRepository) { _reviewBoardRepository = reviewBoardRepository; } void setTaskRepository(TaskRepository taskRepository) { _taskRepository = taskRepository; } }