blob: 80e1fdf27243d15da3ffab3376fa81afcd0136da [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.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.internal.texteditor.SWTUtil;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
public class BuildNotesPage extends WizardPage {
private static final String FOLDER_BIN = "bin"; //$NON-NLS-1$
private static final String EXT_HTML = "html"; //$NON-NLS-1$
private static final String BUILD_NOTES_HTML = "/build_notes.html"; //$NON-NLS-1$
private String FILE_PATH_KEY = "BuildNotesPage.filePath"; //$NON-NLS-1$
private String UPDATE_FILE_KEY = "BuildNotesPage.updateNotesButton"; //$NON-NLS-1$
private Button updateNotesButton;
private boolean updateNotesButtonChecked;
private SyncInfoSet syncInfoSet;
private IDialogSettings settings;
private Text reportText;
private Map<Integer, String> bugSummaryMap;
private boolean validPath;
private Text filePath;
private Button browse;
private IFile iFile;
protected BuildNotesPage(String pageName, String title,
IDialogSettings settings, ImageDescriptor image) {
super(pageName, title, image);
this.settings = settings;
}
@Override
public void createControl(Composite parent) {
GridData data = new GridData(GridData.FILL_BOTH);
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(data);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 3;
updateNotesButton = new Button(composite, SWT.CHECK);
updateNotesButton.setText(Messages.getString("BuildNotesPage.2")); //$NON-NLS-1$
updateNotesButton.setLayoutData(data);
updateNotesButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateNotesButtonChecked = updateNotesButton.getSelection();
if (updateNotesButtonChecked) {
filePath.setEnabled(true);
filePath.setText(filePath.getText());
browse.setEnabled(true);
} else {
filePath.setEnabled(false);
setErrorMessage(null);
browse.setEnabled(false);
}
updateButtons();
}
});
Label label = new Label(composite, SWT.LEFT);
label.setText(Messages.getString("BuildNotesPage.3")); //$NON-NLS-1$
data = new GridData(GridData.FILL_HORIZONTAL);
filePath = new Text(composite, SWT.BORDER);
filePath.setLayoutData(data);
filePath.addModifyListener(e -> {
Path path = new Path(filePath.getText());
validPath = false;
if (!path.isEmpty()) {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
if (path.isValidPath(filePath.getText())
&& file.getParent().exists()) {
if (path.getFileExtension().equals(EXT_HTML)) {
setErrorMessage(null);
validPath = true;
iFile = file;
} else {
setErrorMessage(Messages
.getString("BuildNotesPage.5")); //$NON-NLS-1$
}
} else {
setErrorMessage(Messages.getString("BuildNotesPage.6")); //$NON-NLS-1$
}
} else {
// path is empty
setErrorMessage(Messages.getString("BuildNotesPage.7")); //$NON-NLS-1$
}
updateButtons();
});
browse = new Button(composite, SWT.PUSH);
browse.setText(Messages.getString("BuildNotesPage.8")); //$NON-NLS-1$
browse.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
IResource iResource = buildNotesFileDialog();
if (iResource instanceof IFile) {
IFile iFile = (IFile) iResource;
filePath.setText(iFile.getFullPath().toString());
} else if (iResource instanceof IFolder) {
IFolder iFolder = (IFolder) iResource;
filePath.setText(iFolder.getFullPath().toString()
+ BUILD_NOTES_HTML);
} else if (iResource instanceof IProject) {
IProject iProject = (IProject) iResource;
filePath.setText(iProject.getFullPath().toString()
+ BUILD_NOTES_HTML);
}
}
});
SWTUtil.setButtonDimensionHint(browse);
data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 3;
reportText = new Text(composite, SWT.READ_ONLY | SWT.MULTI | SWT.BORDER
| SWT.WRAP | SWT.V_SCROLL);
reportText.setLayoutData(data);
initialize();
setControl(composite);
}
private void initialize() {
initSelections();
}
/*
* initialize the controls on the page
*/
private void initSelections() {
if (settings == null || settings.get(UPDATE_FILE_KEY) == null
|| settings.get(FILE_PATH_KEY) == null) {
updateNotesButton.setSelection(false);
updateNotesButtonChecked = false;
browse.setEnabled(false);
filePath.setEnabled(false);
return;
} else {
boolean b = settings.getBoolean(UPDATE_FILE_KEY);
updateNotesButton.setSelection(b);
updateNotesButtonChecked = b;
filePath.setText(settings.get(FILE_PATH_KEY));
browse.setEnabled(true);
filePath.setEnabled(true);
}
}
/*
* enable or disable wizard buttons
*/
public void updateButtons() {
if (isUpdateNotesButtonChecked() && !getValidPath()) {
setPageComplete(false);
} else {
setPageComplete(true);
}
}
/*
* if file doesn't already exist, prepare new one otherwise call method to
* write to existing file
*/
public void updateNotesFile() {
if (bugSummaryMap != null && !filePath.isDisposed()) {
Path path = new Path(filePath.getText());
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
final IFile file = root.getFile(path);
if (file.exists()) {
writeUpdate(file);
} else {
if (file.getParent().exists()) {
try {
getContainer().run(true, true, monitor -> {
monitor.beginTask(Messages.getString("BuildNotesPage.11"), //$NON-NLS-1$
100);
StringBuffer buffer = new StringBuffer();
buffer.append("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">\n");
buffer.append("<html>\n\n");
buffer.append("<head>\n");
buffer.append(
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
buffer.append(" <meta name=\"Build\" content=\"Build\">\n");
buffer.append(
" <title>Eclipse Platform Release Notes (3.3) - JFace and Workbench</title>\n");
buffer.append("</head>\n\n");
buffer.append("<body>\n\n");
buffer.append("<h1>Eclipse Platform Build Notes (3.3)<br>\n");
buffer.append("JFace and Workbench</h1>");
try (ByteArrayInputStream c = new ByteArrayInputStream(buffer.toString().getBytes())) {
try {
file.create(c, true, monitor);
} catch (CoreException e1) {
CVSUIPlugin.openError(getShell(), null, null, e1);
}
} catch (IOException e2) {
CVSUIPlugin.openError(getShell(), null, null, e2);
}
monitor.done();
});
} catch (InvocationTargetException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
} catch (InterruptedException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
}
writeUpdate(file);
}
}
}
}
/*
* write update to build notes file
*/
public void writeUpdate(final IFile file) {
BufferedInputStream originalContents = null;
try {
originalContents = new BufferedInputStream(file.getContents());
final StringBuffer buffer = new StringBuffer();
int character;
while ((character = originalContents.read()) != -1) {
buffer.append((char) character);
}
String marker = "</h1>";
SimpleDateFormat formatter = new SimpleDateFormat(
"MMMM dd, yyyy, h:mm a");
Date currentTime = new Date();
String dateString = formatter.format(currentTime);
dateString = dateString.replaceAll("AM", "a.m.");
dateString = dateString.replaceAll("PM", "p.m.");
int index = buffer.indexOf(marker) + marker.length();
if (index != -1) {
StringBuffer insertBuffer = new StringBuffer();
insertBuffer.append("\n<p>Integration Build (" + dateString
+ ")</p>\n");
insertBuffer.append(" <p>Problem reports updated</p>\n");
insertBuffer.append(" <p>\n");
Iterator<Map.Entry<Integer, String>> i = bugSummaryMap.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<Integer, String> entry = i.next();
Integer bug = entry.getKey();
String summary = entry.getValue();
insertBuffer
.append("<a href=\"https://bugs.eclipse.org/bugs/show_bug.cgi?id=");
insertBuffer.append(bug);
insertBuffer.append("\">Bug ");
insertBuffer.append(bug);
insertBuffer.append("</a. ");
insertBuffer.append(summary + "<br>\n");
}
insertBuffer.append(" </p>");
buffer.insert(index, "\n" + insertBuffer.toString());
try {
getContainer().run(true, true, monitor -> {
monitor.beginTask(Messages.getString("BuildNotesPage.38"), 100); //$NON-NLS-1$
ByteArrayInputStream c = new ByteArrayInputStream(buffer.toString().getBytes());
try {
file.setContents(c, true, true, monitor);
c.close();
} catch (CoreException e1) {
CVSUIPlugin.openError(getShell(), null, null, e1);
} catch (IOException e2) {
CVSUIPlugin.openError(getShell(), null, null, e2);
}
monitor.done();
});
} catch (InvocationTargetException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
} catch (InterruptedException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
}
}
} catch (IOException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
} catch (CoreException e) {
CVSUIPlugin.openError(getShell(), null, null, e);
}
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
reportText.setText("");
GetBugsOperation getBugsOperation = new GetBugsOperation(
(ReleaseWizard) getWizard(), syncInfoSet);
getBugsOperation.run(this);
if (bugSummaryMap != null) {
String tempText = outputReport();
if (tempText != null) {
reportText.setText(tempText);
}
}
}
}
public IResource buildNotesFileDialog() {
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
getShell(), new WorkbenchLabelProvider(),
new WorkbenchContentProvider());
// filter for .html files only and exclude bin folders
dialog.addFilter(new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement,
Object element) {
if (element instanceof IFile) {
IFile file = (IFile) element;
IPath path = file.getFullPath();
if (path.getFileExtension().equals(EXT_HTML)) {
return true;
}
} else if (element instanceof IFolder) {
IFolder folder = (IFolder) element;
if (folder.getName().equals(FOLDER_BIN)) {
return false;
}
return true;
} else if (element instanceof IProject) {
return true;
}
return false;
}
});
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
dialog.setAllowMultiple(false);
dialog.setTitle(Messages.getString("BuildNotesPage.42")); //$NON-NLS-1$
dialog.setMessage(Messages.getString("BuildNotesPage.43")); //$NON-NLS-1$
if (dialog.open() == Window.OK) {
Object[] elements = dialog.getResult();
if (elements != null && elements.length > 0) {
if (elements[0] instanceof IFile) {
IFile iFile = (IFile) elements[0];
return iFile;
} else if (elements[0] instanceof IFolder) {
IFolder iFolder = (IFolder) elements[0];
return iFolder;
} else if (elements[0] instanceof IProject) {
IProject iProject = (IProject) elements[0];
return iProject;
}
}
}
return null;
}
public boolean isUpdateNotesButtonChecked() {
return updateNotesButtonChecked;
}
public void setSyncInfoSet(SyncInfoSet syncInfoSet) {
this.syncInfoSet = syncInfoSet;
}
/**
* return string of report
*/
public String outputReport() {
StringBuffer buffer = new StringBuffer();
if (bugSummaryMap.size() < 1) {
buffer.append("The map file has been updated.\n");
} else {
buffer
.append("The map file has been updated for the following Bug changes:\n");
Iterator<Map.Entry<Integer, String>> i = bugSummaryMap.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<Integer, String> entry = i.next();
Integer bug = entry.getKey();
String summary = entry.getValue();
buffer.append("+ Bug " + bug + ". " + summary + "\n");
}
}
buffer.append("\nThe following projects have changed:\n");
IProject[] iProjects = ((ReleaseWizard) getWizard())
.getSelectedProjects();
for (int j = 0; j < iProjects.length; j++) {
buffer.append(iProjects[j].getName() + "\n");
}
return buffer.toString();
}
public void setMap(Map<Integer, String> map) {
this.bugSummaryMap = map;
}
public boolean getValidPath() {
return validPath;
}
public IFile getIFile() {
return iFile;
}
public void saveSettings() {
settings.put(UPDATE_FILE_KEY, updateNotesButtonChecked);
settings.put(FILE_PATH_KEY, filePath.getText());
}
}