blob: 9a59c09ab7b9ac03436cf83f0621a16d3f6fa28b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 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.ui.internal.dialogs;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Map.Entry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogTray;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.osgi.internal.provisional.verifier.CertificateChain;
import org.eclipse.osgi.internal.provisional.verifier.CertificateVerifier;
import org.eclipse.osgi.internal.provisional.verifier.CertificateVerifierFactory;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.about.AboutBundleData;
import org.eclipse.ui.statushandling.StatusManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* @since 3.3
*
*/
public class BundleSigningTray extends DialogTray {
private Text date;
private StyledText certificate;
private AboutBundleData data;
private TrayDialog dialog;
/**
*
*/
public BundleSigningTray(TrayDialog dialog) {
this.dialog = dialog;
}
public void setData(AboutBundleData data) {
this.data = data;
startJobs();
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.DialogTray#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
Composite content = new Composite(parent, SWT.NONE);
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
GridLayout layout = new GridLayout(2, false);
content.setLayout(layout);
// date
Color backgroundColor = parent.getDisplay().getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND);
{
Label label = new Label(content, SWT.NONE);
label.setText(WorkbenchMessages.BundleSigningTray_Signing_Date);
GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
date = new Text(content, SWT.READ_ONLY);
GC gc = new GC(date);
gc.setFont(JFaceResources.getDialogFont());
Point size = gc.stringExtent(DateFormat.getDateTimeInstance().format(new Date()));
data.widthHint = size.x;
gc.dispose();
date.setText(WorkbenchMessages.BundleSigningTray_Working);
date.setLayoutData(data);
date.setBackground(backgroundColor);
}
// signer
{
Label label = new Label(content, SWT.NONE);
label.setText(WorkbenchMessages.BundleSigningTray_Signing_Certificate);
GridData data = new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false);
data.horizontalSpan = 2;
data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.horizontalSpan = 2;
certificate = new StyledText(content, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
certificate.setText(WorkbenchMessages.BundleSigningTray_Working);
certificate.setLayoutData(data);
}
// problems
// {
// Label label = new Label(content, SWT.NONE);
// label.setText("Problems:"); //$NON-NLS-1$
//
// }
Dialog.applyDialogFont(content);
startJobs(); // start the jobs that will prime the content
return content;
}
/**
*
*/
private void startJobs() {
if (!isOpen())
return;
certificate.setText(WorkbenchMessages.BundleSigningTray_Working);
date.setText(WorkbenchMessages.BundleSigningTray_Working);
final BundleContext bundleContext = WorkbenchPlugin.getDefault()
.getBundleContext();
final ServiceReference certRef = bundleContext
.getServiceReference(CertificateVerifierFactory.class.getName());
if (certRef == null) {
StatusManager.getManager().handle(
new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH,
WorkbenchMessages.BundleSigningTray_Cant_Find_Service),
StatusManager.LOG);
return;
}
final CertificateVerifierFactory certFactory = (CertificateVerifierFactory) bundleContext
.getService(certRef);
if (certFactory == null) {
StatusManager.getManager().handle(
new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH,
WorkbenchMessages.BundleSigningTray_Cant_Find_Service),
StatusManager.LOG);
return;
}
final AboutBundleData myData = data;
final Job signerJob = new Job(NLS.bind(WorkbenchMessages.BundleSigningTray_Determine_Signer_For, myData.getId())) {
protected IStatus run(IProgressMonitor monitor) {
try {
if (myData != data)
return Status.OK_STATUS;
CertificateVerifier verifier = certFactory.getVerifier(myData
.getBundle());
if (myData != data)
return Status.OK_STATUS;
CertificateChain[] chains = verifier.getChains();
final String signerText, dateText;
final Shell dialogShell = dialog.getShell();
if (!isOpen() && BundleSigningTray.this.data == myData)
return Status.OK_STATUS;
if (chains.length == 0) {
signerText = WorkbenchMessages.BundleSigningTray_Unsigned;
dateText = WorkbenchMessages.BundleSigningTray_Unsigned;
} else {
Properties [] certs = parseCerts(chains[0].getChain());
if (certs.length == 0)
signerText = WorkbenchMessages.BundleSigningTray_Unknown;
else {
StringBuffer buffer = new StringBuffer();
for (Iterator i = certs[0].entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Entry) i.next();
buffer.append(entry.getKey());
buffer.append('=');
buffer.append(entry.getValue());
if (i.hasNext())
buffer.append('\n');
}
signerText = buffer.toString();
}
Date signDate = chains[0].getSigningTime();
if (signDate != null)
dateText = DateFormat.getDateTimeInstance().format(
signDate);
else
dateText = WorkbenchMessages.BundleSigningTray_Unknown;
}
Display display = dialogShell.getDisplay();
display.asyncExec(new Runnable() {
public void run() {
// check to see if the tray is still visible and if we're still looking at the same item
if (!isOpen() && BundleSigningTray.this.data != myData)
return;
certificate.setText(signerText);
date.setText(dateText);
}
});
} catch (IOException e) {
return new Status(IStatus.ERROR,
WorkbenchPlugin.PI_WORKBENCH, e.getMessage(), e);
}
return Status.OK_STATUS;
}
};
signerJob.setSystem(true);
signerJob.belongsTo(signerJob);
signerJob.schedule();
Job cleanup = new Job(WorkbenchMessages.BundleSigningTray_Unget_Signing_Service) {
protected IStatus run(IProgressMonitor monitor) {
try {
getJobManager().join(signerJob, monitor);
} catch (OperationCanceledException e) {
} catch (InterruptedException e) {
}
bundleContext.ungetService(certRef);
return Status.OK_STATUS;
}
};
cleanup.setSystem(true);
cleanup.schedule();
}
/**
*
*/
private boolean isOpen() {
return certificate != null && !certificate.isDisposed();
}
private Properties[] parseCerts(String certString) {
List certs = new ArrayList();
StringTokenizer toker = new StringTokenizer(certString, ";"); //$NON-NLS-1$
while (toker.hasMoreTokens()) {
Map cert = parseCert(toker.nextToken());
if (cert != null)
certs.add(cert);
}
return (Properties []) certs.toArray(new Properties[certs.size()]);
}
/**
* @param certString
* @return
*/
private Properties parseCert(String certString) {
StringTokenizer toker = new StringTokenizer(certString, ","); //$NON-NLS-1$
Properties cert = new Properties();
while (toker.hasMoreTokens()) {
String pair = toker.nextToken();
int idx = pair.indexOf('=');
if (idx > 0 && idx < pair.length() - 2) {
String key = pair.substring(0, idx).trim();
String value = pair.substring(idx + 1).trim();
if (value.length() > 2) {
if (value.charAt(0) == '\"')
value = value.substring(1);
if (value.charAt(value.length() - 1) == '\"')
value = value.substring(0, value.length() - 1);
}
cert.setProperty(key, value);
}
}
return cert;
}
}