blob: 83d3476051c16d09ca5c0816989640bb7aeed07f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.releng.tools;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.releng.tools.preferences.MapProjectPreferencePage;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.operations.CommitOperation;
import org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation;
import org.eclipse.team.internal.ui.ITeamUIImages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.dialogs.IPromptCondition;
import org.eclipse.team.internal.ui.dialogs.PromptingDialog;
public class ReleaseWizard extends Wizard {
// Dialog store constants
private static final String BOUNDS_HEIGHT= "bounds.height"; //$NON-NLS-1$
private static final String BOUNDS_WIDTH= "bounds.width"; //$NON-NLS-1$
private static final String BOUNDS_Y= "bounds.y"; //$NON-NLS-1$
private static final String BOUNDS_X= "bounds.x"; //$NON-NLS-1$
private MapProjectSelectionPage mapSelectionPage;
private ProjectSelectionPage projectSelectionPage;
private TagPage tagPage;
private ProjectComparePage projectComparePage;
private MapFileComparePage mapComparePage;
private CommitCommentPage commentPage;
private BuildNotesPage buildNotesPage;
private ValidatePage validatePage;
private Dialog parentDialog;
private IDialogSettings section;
private MapProject mapProject;
private IProject[] preSelectedProjects;
private IProject[] selectedProjects;
private IPreferenceStore preferenceStore;
private boolean defaultBeingUsed;
public ReleaseWizard() {
setWindowTitle("Release"); //$NON-NLS-1$
IDialogSettings settings = RelEngPlugin.getDefault().getDialogSettings();
section = settings.getSection("ReleaseWizard");//$NON-NLS-1$
if (section == null) {
section = settings.addNewSection("ReleaseWizard");//$NON-NLS-1$
}
setDialogSettings(section);
preferenceStore = RelEngPlugin.getDefault().getPreferenceStore();
}
/*
* @see org.eclipse.jface.wizard.Wizard#createPageControls(org.eclipse.swt.widgets.Composite)
* @since 3.1
*/
@Override
public void createPageControls(Composite pageContainer) {
super.createPageControls(pageContainer);
if (getDialogSettings().get(BOUNDS_X) != null) {
int x= getDialogSettings().getInt(BOUNDS_X);
int y= getDialogSettings().getInt(BOUNDS_Y);
int width= getDialogSettings().getInt(BOUNDS_WIDTH);
int height= getDialogSettings().getInt(BOUNDS_HEIGHT);
getShell().setBounds(x, y, width, height);
}
getShell().addControlListener(new ControlListener() {
@Override
public void controlMoved(ControlEvent e) {
storeBounds(e);
}
@Override
public void controlResized(ControlEvent e) {
storeBounds(e);
}
private void storeBounds(ControlEvent e) {
Rectangle bounds= getShell().getBounds();
getDialogSettings().put(BOUNDS_X, bounds.x);
getDialogSettings().put(BOUNDS_Y, bounds.y);
getDialogSettings().put(BOUNDS_WIDTH, bounds.width);
getDialogSettings().put(BOUNDS_HEIGHT, bounds.height);
}
});
}
public boolean execute(Shell shell) {
setNeedsProgressMonitor(true);
WizardDialog dialog = new WizardDialog(shell, this);
setParentDialog(dialog);
return (dialog.open() == Window.OK);
}
/**
* @see org.eclipse.jface.wizard.IWizard#addPages()
*/
@Override
public void addPages() {
defaultBeingUsed = false;
if (preferenceStore.getBoolean(MapProjectPreferencePage.USE_DEFAULT_MAP_PROJECT) &&
(preferenceStore.getString(MapProjectPreferencePage.SELECTED_MAP_PROJECT_PATH).length() > 1)) {
String path = preferenceStore.getString(MapProjectPreferencePage.SELECTED_MAP_PROJECT_PATH);
try {
mapProject = new MapProject(ResourcesPlugin.getWorkspace().getRoot().getProject(path));
defaultBeingUsed = true;
}
catch (CoreException e) {
//this is ok, we will use the mapSelectionPage instead
}
}
ImageDescriptor wizardPageImageDescriptor = TeamUIPlugin
.getImageDescriptor(ITeamUIImages.IMG_WIZBAN_SHARE);
if (!defaultBeingUsed)
addMapSelectionPage(wizardPageImageDescriptor);
projectSelectionPage = new ProjectSelectionPage("ProjectSelectionPage", //$NON-NLS-1$
Messages.getString("ReleaseWizard.6"), //$NON-NLS-1$
section, wizardPageImageDescriptor);
projectSelectionPage.setDescription(Messages
.getString("ReleaseWizard.7")); //$NON-NLS-1$
addPage(projectSelectionPage);
tagPage = new TagPage("TagPage", //$NON-NLS-1$
Messages.getString("ReleaseWizard.9"), //$NON-NLS-1$
section,
wizardPageImageDescriptor);
tagPage.setDescription(Messages.getString("ReleaseWizard.10")); //$NON-NLS-1$
addPage(tagPage);
projectComparePage = new ProjectComparePage("ProjectComparePage", //$NON-NLS-1$
Messages.getString("ReleaseWizard.12"), //$NON-NLS-1$
section,
wizardPageImageDescriptor);
projectComparePage.setDescription(Messages.getString("ReleaseWizard.13")); //$NON-NLS-1$
addPage(projectComparePage);
buildNotesPage = new BuildNotesPage("Build Notes Page", //$NON-NLS-1$
Messages.getString("ReleaseWizard.1"), //$NON-NLS-1$
section,
wizardPageImageDescriptor);
buildNotesPage.setDescription(Messages.getString("ReleaseWizard.0")); //$NON-NLS-1$
addPage(buildNotesPage);
mapComparePage = new MapFileComparePage("MapComparePage", //$NON-NLS-1$
Messages.getString("ReleaseWizard.15"), //$NON-NLS-1$
wizardPageImageDescriptor);
mapComparePage.setDescription(Messages.getString("ReleaseWizard.16")); //$NON-NLS-1$
addPage(mapComparePage);
commentPage = new CommitCommentPage(parentDialog, "Commit", //$NON-NLS-1$
Messages.getString("ReleaseWizard.18"), //$NON-NLS-1$
wizardPageImageDescriptor,
Messages.getString("ReleaseWizard.19")); //$NON-NLS-1$
addPage(commentPage);
validatePage = new ValidatePage(parentDialog, "ValidatePage", //$NON-NLS-1$
Messages.getString("ReleaseWizard.validatePageTitle"), //$NON-NLS-1$
wizardPageImageDescriptor);
addPage(validatePage);
if (defaultBeingUsed) broadcastMapProjectChange(mapProject);
}
/*
* @see org.eclipse.jface.wizard.Wizard#dispose()
* @since 3.7
*/
@Override
public void dispose() {
if (mapProject != null) {
mapProject.dispose();
mapProject= null;
}
super.dispose();
}
private void addMapSelectionPage(ImageDescriptor wizardPageImageDescriptor) {
mapSelectionPage = new MapProjectSelectionPage(
"MapProjectSelectionPage", //$NON-NLS-1$
Messages.getString("ReleaseWizard.4"), //$NON-NLS-1$
section, wizardPageImageDescriptor);
mapSelectionPage.setDescription(Messages.getString("ReleaseWizard.3")); //$NON-NLS-1$
addPage(mapSelectionPage);
}
/*
* commit buildnotes file if update option selected
*/
public boolean buildNotesOperation() {
if (buildNotesPage.isUpdateNotesButtonChecked() && projectComparePage.isBuildNotesButtonChecked()) {
buildNotesPage.updateNotesFile();
try {
getContainer().run(true, true, monitor -> {
IFile iFile = buildNotesPage.getIFile();
IProject iProject = iFile.getProject();
monitor.beginTask(Messages.getString("ReleaseWizard.20"), 100); //$NON-NLS-1$
new CommitOperation(null,
RepositoryProviderOperation.asResourceMappers(new IResource[] { iProject }),
new Command.LocalOption[0], commentPage.getComment()).run(monitor);
monitor.done();
});
} catch (InterruptedException e) {
// Cancelled.
return false;
} catch (InvocationTargetException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
}
checkProjects();
}
return true;
}
/*
* add project of build notes file if not already in selected projects
*/
public void checkProjects() {
IProject[] temp = new IProject[selectedProjects.length + 1];
for (int i = 0; i < selectedProjects.length; i++) {
if (selectedProjects[i] == buildNotesPage.getIFile().getProject()) {
return;
}
}
System.arraycopy(selectedProjects, 0, temp, 0, selectedProjects.length);
temp[temp.length - 1] = buildNotesPage.getIFile().getProject();
selectedProjects = temp;
}
/**
* @see org.eclipse.jface.wizard.Wizard#performFinish()
*/
@Override
public boolean performFinish() {
if(!isProjectSelected())return false;
if (projectSelectionPage.isCompareButtonChecked() && !buildNotesOperation()) {
return true; // Build notes file update cancelled. Close dialog.
}
try {
getContainer().run(true, true, monitor -> {
CVSTag tag = new CVSTag(tagPage.getTagString(), CVSTag.VERSION);
TagAndReleaseOperation operation = new TagAndReleaseOperation(null, mapProject, selectedProjects, tag,
commentPage.getComment());
if (tagPage.isMoveButtonSelected()) {
operation.moveTag();
}
monitor.beginTask(Messages.getString("ReleaseWizard.21"), 100); //$NON-NLS-1$
operation.run(SubMonitor.convert(monitor, 90));
if (operation.isMapFileUpdated()) {
try {
if (tagPage.isValidateButtonSelected()) {
try {
getShell().getDisplay().asyncExec(() -> {
if (parentDialog instanceof WizardDialog)
((WizardDialog) parentDialog).showPage(validatePage);
});
validateRelease(SubMonitor.convert(monitor, 10));
} catch (TeamException e) {
throw new InvocationTargetException(e);
}
}
} finally {
monitor.done();
}
} else {
// The map file update didn't occur and no exception was
// thrown.
// Let the user know of the failure
IStatus[] errors = operation.getErrors();
IStatus status;
if (errors.length == 0) {
status = new Status(IStatus.ERROR, RelEngPlugin.ID, 0, Messages.getString("ReleaseWizard.22"), //$NON-NLS-1$
null);
} else if (errors.length == 1) {
status = errors[0];
} else {
status = new MultiStatus(RelEngPlugin.ID, 0, errors, Messages.getString("ReleaseWizard.23"), //$NON-NLS-1$
null);
}
ErrorDialog.openError(getShell(), Messages.getString("ReleaseWizard.24"), //$NON-NLS-1$
Messages.getString("ReleaseWizard.25"), //$NON-NLS-1$
status, IStatus.ERROR | IStatus.WARNING);
}
});
if (!defaultBeingUsed) {
mapSelectionPage.saveSettings();
updatePreferenceStore();
}
projectSelectionPage.saveSettings();
projectComparePage.saveSettings();
buildNotesPage.saveSettings();
tagPage.saveSettings();
return true;
} catch (InterruptedException e) {
// Cancelled. Ignore and close dialog
return true;
} catch (InvocationTargetException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
}
return false;
}
private void updatePreferenceStore() {
preferenceStore.setValue(MapProjectPreferencePage.USE_DEFAULT_MAP_PROJECT, mapSelectionPage.useDefaultMapProject());
String fullPath = mapSelectionPage.getSelectedMapProject().getProject().getFullPath().toString();
preferenceStore.setValue(MapProjectPreferencePage.SELECTED_MAP_PROJECT_PATH, fullPath);
}
public void setParentDialog(Dialog p) {
this.parentDialog = p;
}
@Override
public IWizardPage getNextPage(IWizardPage page) {
if (page == mapSelectionPage) {
if (selectedProjects == null && preSelectedProjects != null) {
projectSelectionPage.setSelection(preSelectedProjects);
selectedProjects= preSelectedProjects;
}
return projectSelectionPage;
}
if (page == projectSelectionPage) {
IProject[] projects = projectSelectionPage.getCheckedProjects();
if (projects != null && projects.length > 0){
selectedProjects = projects;
}
if (projectSelectionPage.isCompareButtonChecked()){
return projectComparePage;
}
else
return tagPage;
}
if (page == tagPage) {
if (tagPage.compareButtonSelected()){
mapComparePage.setTag(tagPage.getTagString());
return mapComparePage;
}
if (tagPage.commitButtonSelected())
return commentPage;
}
if (page == mapComparePage)
return commentPage;
if (page == projectComparePage) {
if (projectComparePage.isBuildNotesButtonChecked()) {
buildNotesPage.setSyncInfoSet(projectComparePage
.getSyncInfoSet());
return buildNotesPage;
}
return tagPage;
}
if (page == buildNotesPage) {
return tagPage;
}
return null;
}
public void setPreSelectedProjects(IResource[] resources) {
if (resources.length < 1) {
preSelectedProjects = null;
} else {
Set<IProject> list = new HashSet<>();
for (int i = 0; i < resources.length; i++) {
list.add(resources[i].getProject());
}
preSelectedProjects = list.toArray(new IProject[list.size()]);
}
}
// Prompt for any uncommitted changes
protected IProject[] performPrompting(IProject[] projects) {
IResource[] resources;
PromptingDialog prompt = new PromptingDialog(getShell(), projects,
getPromptCondition(projects), Messages.getString("TagAction_uncommittedChangesTitle")); //$NON-NLS-1$
try {
resources = prompt.promptForMultiple();
} catch(InterruptedException e) {
return null;
}
if(resources.length == 0) {
return null;
}
projects = new IProject[resources.length ];
for(int i = 0; i < resources.length; i++){
if(resources[i] instanceof IProject)
projects[i] = (IProject)resources[i];
}
return projects;
}
protected IPromptCondition getPromptCondition(IResource[] resources) {
return new IPromptCondition() {
@Override
public boolean needsPrompt(IResource resource) {
return CVSLightweightDecorator.isDirty(resource);
}
@Override
public String promptMessage(IResource resource) {
return NLS.bind(Messages.getString("TagAction_uncommittedChanges"), new String[] { resource.getName() }); //$NON-NLS-1$
}
};
}
public IProject[] getSelectedProjects(){
return selectedProjects;
}
//the update will happen when (1)from project selection page to compare project page or (2)from
//project selection page to Enter Tag page. It calls shouldRemove() to determine the projects to keep
public void updateSelectedProject(){
selectedProjects = projectSelectionPage.getCheckedProjects();
selectedProjects = performPrompting(selectedProjects);
projectSelectionPage.setSelection(selectedProjects);
}
public void setSelectedProjects(IResource[] projects){
if(projects == null) selectedProjects = null;
else {
selectedProjects = new IProject[projects.length];
for(int i = 0; i < projects.length; i++){
selectedProjects[i] = (IProject)projects[i];
}
}
}
protected ProjectSelectionPage getProjectSelectionPage(){
return projectSelectionPage;
}
//This method is called if validate button in TagPage is checked
private void validateRelease(IProgressMonitor monitor) throws TeamException{
ProjectValidationDialog.validateRelease(getShell(), selectedProjects, mapProject.getTagsFor(selectedProjects), monitor);
}
private boolean isProjectSelected(){
if (selectedProjects == null || selectedProjects.length == 0){
return false;
}
return true;
}
public IProject[] getPreSelectedProjects(){
return preSelectedProjects;
}
@Override
public boolean canFinish() {
// There must be projects selected
if (!isProjectSelected()) {
return false;
}
// There must be a tag
if (!tagPage.isPageComplete()) {
return false;
}
IWizardPage currentPage = getContainer().getCurrentPage();
if (currentPage == validatePage)
return false;
// Force map comparison if option set by user
if(currentPage == tagPage){
if(tagPage.compareButtonSelected()){
return false;
}
}
return true;
}
public MapProject getMapProject(){
return mapProject;
}
public void broadcastMapProjectChange(MapProject m){
mapProject = m;
projectSelectionPage.updateMapProject(m);
projectComparePage.updateMapProject(m);
mapComparePage.updateMapProject(m);
}
}