| /******************************************************************************* |
| * 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; |
| } |
| |
| } |