diff options
19 files changed, 767 insertions, 42 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF index ecda9a06c..485fee5c6 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF @@ -41,6 +41,7 @@ Import-Package: javax.xml.parsers, org.eclipse.equinox.internal.p2.persistence, org.eclipse.equinox.internal.p2.repository, org.eclipse.equinox.internal.p2.repository.helpers, + org.eclipse.equinox.internal.provisional.p2.core.eventbus, org.eclipse.equinox.internal.provisional.p2.repository, org.eclipse.equinox.p2.core;version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.core.spi;version="[2.0.0,3.0.0)", @@ -49,7 +50,7 @@ Import-Package: javax.xml.parsers, org.eclipse.equinox.p2.repository.artifact.spi;version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.repository.spi;version="[2.0.0,3.0.0)", org.eclipse.internal.provisional.equinox.p2.jarprocessor;resolution:=optional, - org.eclipse.osgi.service.datalocation;version="[1.3.0, 2.0.0)", + org.eclipse.osgi.service.datalocation;version="[1.3.0,2.0.0)", org.eclipse.osgi.signedcontent;version="1.0.0", org.eclipse.osgi.util;version="1.1.0", org.osgi.framework;version="1.3.0", diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorEvent.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorEvent.java new file mode 100644 index 000000000..83213c857 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorEvent.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River 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: + * Wind River - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.artifact.repository; + +import java.util.EventObject; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; + +public class MirrorEvent extends EventObject { + + private static final long serialVersionUID = -2958057566692590943L; + + private IStatus downloadStatus; + + private IArtifactRepository repository; + + private IArtifactDescriptor descriptor; + + public MirrorEvent(IArtifactRepository repo, IArtifactDescriptor descriptor, IStatus downloadStatus) { + super(descriptor); + this.repository = repo; + this.descriptor = descriptor; + this.downloadStatus = downloadStatus; + } + + public IArtifactRepository getSourceRepository() { + return repository; + } + + public IArtifactDescriptor getMirroredDescriptor() { + return descriptor; + } + + public IStatus getDownloadStatus() { + return downloadStatus; + } +} diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java index b0daef205..499830240 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java +++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -23,6 +23,7 @@ import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifact import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; import org.eclipse.equinox.internal.p2.repository.Transport; import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStepHandler; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.internal.provisional.p2.repository.IStateful; import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.equinox.p2.metadata.IArtifactKey; @@ -192,6 +193,9 @@ public class MirrorRequest extends ArtifactRequest { lastResult = transferSingle(destinationDescriptor, sourceDescriptor, monitor); allResults.add(lastResult); } while (lastResult.getSeverity() == IStatus.ERROR && lastResult.getCode() == IArtifactRepository.CODE_RETRY && counter++ < MAX_RETRY_REQUEST); + IProvisioningEventBus bus = (IProvisioningEventBus) source.getProvisioningAgent().getService(IProvisioningEventBus.SERVICE_NAME); + if (bus != null) + bus.publishEvent(new MirrorEvent(source, sourceDescriptor, lastResult.isOK() ? lastResult : (allResults.getChildren().length <= 1 ? lastResult : allResults))); if (lastResult.isOK()) { collectStats(sourceDescriptor, monitor); return lastResult; diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java index 79970410d..0c4c1dd76 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java +++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -25,12 +25,13 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.equinox.internal.p2.artifact.processors.md5.MD5Verifier; import org.eclipse.equinox.internal.p2.artifact.repository.*; +import org.eclipse.equinox.internal.p2.artifact.repository.Activator; import org.eclipse.equinox.internal.p2.artifact.repository.Messages; import org.eclipse.equinox.internal.p2.core.helpers.FileUtils; import org.eclipse.equinox.internal.p2.metadata.ArtifactKey; import org.eclipse.equinox.internal.p2.metadata.expression.CompoundIterator; import org.eclipse.equinox.internal.p2.metadata.index.IndexProvider; -import org.eclipse.equinox.internal.p2.repository.Transport; +import org.eclipse.equinox.internal.p2.repository.*; import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.*; import org.eclipse.equinox.internal.provisional.p2.repository.IStateful; import org.eclipse.equinox.p2.core.IProvisioningAgent; @@ -557,18 +558,28 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme } // TODO: optimize and ensure manifest is written first File zipFile = null; + long start = System.currentTimeMillis(); + long totalArtifactSize = 0; try { zipFile = File.createTempFile(artifactFolder.getName(), JAR_EXTENSION, null); FileUtils.zip(artifactFolder.listFiles(), null, zipFile, FileUtils.createRootPathComputer(artifactFolder)); FileInputStream fis = new FileInputStream(zipFile); - FileUtils.copyStream(fis, true, destination, false); + totalArtifactSize += FileUtils.copyStream(fis, true, destination, false); } catch (IOException e) { return reportStatus(descriptor, destination, new Status(IStatus.ERROR, Activator.ID, e.getMessage())); } finally { if (zipFile != null) zipFile.delete(); } - return reportStatus(descriptor, destination, Status.OK_STATUS); + long end = System.currentTimeMillis(); + DownloadStatus statusWithDownloadSpeed = new DownloadStatus(IStatus.OK, Activator.ID, Status.OK_STATUS.getMessage()); + try { + statusWithDownloadSpeed.setFileSize(totalArtifactSize); + statusWithDownloadSpeed.setTransferRate(totalArtifactSize / Math.max((end - start), 1) * 1000); + } catch (NumberFormatException e) { + // ignore + } + return reportStatus(descriptor, destination, statusWithDownloadSpeed); } //download from the best available mirror @@ -607,8 +618,9 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme int expected_loops = new Double(in.length() / bufferSize).intValue() + 1; // +1: also count the initial run SubMonitor sub = SubMonitor.convert(monitor, Messages.downloading + in.getName(), expected_loops); // Be optimistic about the outcome of this... - IStatus status = Status.OK_STATUS; + IStatus status = new DownloadStatus(IStatus.OK, Activator.ID, Status.OK_STATUS.getMessage()); try { + long start = System.currentTimeMillis(); FileInputStream stream = new FileInputStream(in); try { int len; @@ -619,6 +631,10 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme } finally { stream.close(); } + long end = System.currentTimeMillis(); + ((DownloadStatus) status).setFileSize(in.length()); + ((DownloadStatus) status).setLastModified(in.lastModified()); + ((DownloadStatus) status).setTransferRate(in.length() / Math.max((end - start), 1) * 1000); } catch (IOException ioe) { status = new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.error_copying_local_file, in.getAbsolutePath()), ioe); } @@ -732,6 +748,8 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme if (monitor.isCanceled()) return Status.CANCEL_STATUS; + ProgressStatistics.setProvisioningAgent(getProvisioningAgent()); + final MultiStatus overallStatus = new MultiStatus(Activator.ID, IStatus.OK, null, null); LinkedList<IArtifactRequest> requestsPending = new LinkedList<IArtifactRequest>(Arrays.asList(requests)); diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/CollectEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/CollectEvent.java new file mode 100644 index 000000000..fdd62f2a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/CollectEvent.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River 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: + * Wind River - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.engine; + +import java.util.EventObject; +import org.eclipse.equinox.p2.engine.ProvisioningContext; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRequest; + +public class CollectEvent extends EventObject { + + private static final long serialVersionUID = 5782796765127875200L; + /** + * It means the overall collecting requests are started. + */ + public static final int TYPE_OVERALL_START = 1; + /** + * It means the overall collecting requests are finished. + */ + public static final int TYPE_OVERALL_END = 2; + /** + * It means the collecting requests related to a special repository are started. + * See {@link CollectEvent#getRepository()} + */ + public static final int TYPE_REPOSITORY_START = 3; + /** + * It means the collecting requests related to a special repository are end. + * See {@link CollectEvent#getRepository()} + */ + public static final int TYPE_REPOSITORY_END = 4; + + private IArtifactRepository artifactRepo; + private IArtifactRequest[] requests; + + private ProvisioningContext context; + + private int type; + + public CollectEvent(int type, IArtifactRepository artifactRepo, ProvisioningContext context, IArtifactRequest[] requests) { + super(requests); + this.type = type; + this.artifactRepo = artifactRepo; + this.context = context; + this.requests = requests; + } + + public int getType() { + return type; + } + + /** + * Return the associated repository if the downloading requests are related to a special repository + * @return the associated repository or <code>null</code> if the repository is unknown + */ + public IArtifactRepository getRepository() { + return artifactRepo; + } + + public IArtifactRequest[] getDownloadRequests() { + return requests; + } + + public ProvisioningContext getContext() { + return context; + } +} diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/DownloadManager.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/DownloadManager.java index 8daa26bae..d1df5cf0c 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/DownloadManager.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/DownloadManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -14,6 +14,7 @@ package org.eclipse.equinox.internal.p2.engine; import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.equinox.internal.p2.engine.phases.Collect; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.engine.ProvisioningContext; import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil; @@ -107,7 +108,9 @@ public class DownloadManager { SubMonitor monitor = SubMonitor.convert(mon, requestsToProcess.size()); for (int i = 0; i < repositories.length && !requestsToProcess.isEmpty() && !monitor.isCanceled(); i++) { IArtifactRequest[] requests = getRequestsForRepository(repositories[i]); + publishDownloadEvent(new CollectEvent(CollectEvent.TYPE_REPOSITORY_START, repositories[i], provContext, requests)); IStatus dlStatus = repositories[i].getArtifacts(requests, monitor.newChild(requests.length)); + publishDownloadEvent(new CollectEvent(CollectEvent.TYPE_REPOSITORY_END, repositories[i], provContext, requests)); if (dlStatus.getSeverity() == IStatus.CANCEL) return; filterUnfetched(); @@ -115,6 +118,12 @@ public class DownloadManager { } } + private void publishDownloadEvent(CollectEvent event) { + IProvisioningEventBus bus = (IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME); + if (bus != null) + bus.publishEvent(event); + } + private IArtifactRequest[] getRequestsForRepository(IArtifactRepository repository) { ArrayList<IArtifactRequest> applicable = new ArrayList<IArtifactRequest>(); for (IArtifactRequest request : requestsToProcess) { diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/InstallableUnitEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/InstallableUnitEvent.java index 8eb5c0cfd..6d4424892 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/InstallableUnitEvent.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/InstallableUnitEvent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -7,14 +7,14 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Wind River - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.engine; -import org.eclipse.equinox.p2.engine.IProfile; - import java.util.EventObject; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.p2.engine.IProfile; import org.eclipse.equinox.p2.engine.spi.Touchpoint; import org.eclipse.equinox.p2.metadata.IInstallableUnit; @@ -24,6 +24,8 @@ import org.eclipse.equinox.p2.metadata.IInstallableUnit; public class InstallableUnitEvent extends EventObject { public static final int UNINSTALL = 0; public static final int INSTALL = 1; + public static final int UNCONFIGURE = 2; + public static final int CONFIGURE = 3; private static final long serialVersionUID = 3318712818811459886L; private String phaseId; @@ -45,8 +47,8 @@ public class InstallableUnitEvent extends EventObject { this.prePhase = prePhase; this.profile = profile; this.iu = iu; - if (type != UNINSTALL && type != INSTALL) - throw new IllegalArgumentException(Messages.InstallableUnitEvent_type_not_install_or_uninstall); + if (type != UNINSTALL && type != INSTALL && type != UNCONFIGURE && type != CONFIGURE) + throw new IllegalArgumentException(Messages.InstallableUnitEvent_type_not_install_or_uninstall_or_configure); this.type = type; this.result = result; this.touchpoint = touchpoint; @@ -88,4 +90,12 @@ public class InstallableUnitEvent extends EventObject { public boolean isUninstall() { return type == UNINSTALL; } + + public boolean isConfigure() { + return type == CONFIGURE; + } + + public boolean isUnConfigure() { + return type == UNCONFIGURE; + } } diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java index 453670e7f..9c9710c4a 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -39,7 +39,7 @@ public class Messages extends NLS { public static String error_parsing_profile; public static String error_persisting_profile; public static String forced_action_execute_error; - public static String InstallableUnitEvent_type_not_install_or_uninstall; + public static String InstallableUnitEvent_type_not_install_or_uninstall_or_configure; public static String io_FailedRead; public static String io_NotFound; public static String not_current_operand; diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java index 14782d57b..f57a4829a 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -13,6 +13,7 @@ package org.eclipse.equinox.internal.p2.engine; import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.p2.engine.IProfile; import org.eclipse.equinox.p2.engine.ProvisioningContext; import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; @@ -66,9 +67,21 @@ public abstract class Phase { return getClass().getName() + " - " + this.weight; //$NON-NLS-1$ } + private void broadcastPhaseEvent(EngineSession session, Operand[] operands, int type) { + IProvisioningEventBus bus = (IProvisioningEventBus) session.getAgent().getService(IProvisioningEventBus.SERVICE_NAME); + if (bus != null) { + bus.publishEvent(getPhaseEvent(operands, type)); + } + } + + protected PhaseEvent getPhaseEvent(final Operand[] operands, int type) { + return new PhaseEvent(phaseId, operands, type); + } + void perform(MultiStatus status, EngineSession session, Operand[] operands, IProgressMonitor monitor) { SubMonitor subMonitor = SubMonitor.convert(monitor, prePerformWork + mainPerformWork + postPerformWork); session.recordPhaseEnter(this); + broadcastPhaseEvent(session, operands, PhaseEvent.TYPE_START); prePerform(status, session, subMonitor.newChild(prePerformWork)); if (status.matches(IStatus.ERROR | IStatus.CANCEL)) return; @@ -85,6 +98,7 @@ public abstract class Phase { phaseParameters.clear(); if (status.matches(IStatus.ERROR | IStatus.CANCEL)) return; + broadcastPhaseEvent(session, operands, PhaseEvent.TYPE_END); session.recordPhaseExit(this); subMonitor.done(); } diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseEvent.java new file mode 100644 index 000000000..2461242a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseEvent.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River 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: + * Wind River - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.engine; + +import java.util.EventObject; + +public class PhaseEvent extends EventObject { + + private static final long serialVersionUID = 8971345257149340658L; + + public static final int TYPE_START = 1; + public static final int TYPE_END = 2; + + private int type; + + private String phaseId; + + private Operand[] operands; + + public PhaseEvent(String phaseId, Operand[] operands, int type) { + super(operands); + this.phaseId = phaseId; + this.type = type; + this.operands = operands; + } + + public String getPhaseId() { + return phaseId; + } + + public int getType() { + return type; + } + + public Operand[] getOperands() { + return operands; + } +} diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties index b8e98c09d..597ef540d 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2007, 2011 IBM Corporation and others. +# Copyright (c) 2007, 2012 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 @@ -90,7 +90,7 @@ rollingback_error=An error was detected while performing the engine operation an rollingback_cancel=The engine operation was cancelled and the changes are being rolled back. Engine_Operation_Canceled_By_User=Operation canceled by the user. -InstallableUnitEvent_type_not_install_or_uninstall=type must be either UNINSTALL(0) or INSTALL(1) +InstallableUnitEvent_type_not_install_or_uninstall_or_configure=type must be either UNINSTALL(0) or INSTALL(1) or UNCONFIGURE(2) or CONFIGURE(3) CertificateChecker_CertificateError=An invalid certificate was found. CertificateChecker_CertificateRejected=One or more certificates rejected. Cannot proceed with installation. CertificateChecker_KeystoreConnectionError=Cannot connect to keystore. diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java index 92ad013d4..df2435eda 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -15,6 +15,7 @@ import java.util.*; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.equinox.internal.p2.engine.*; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.engine.*; import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; @@ -69,11 +70,24 @@ public class Collect extends InstallableUnitPhase { ProvisioningContext context = (ProvisioningContext) parameters.get(PARM_CONTEXT); IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + List<IArtifactRequest> totalArtifactRequests = new ArrayList<IArtifactRequest>(artifactRequests.size()); DownloadManager dm = new DownloadManager(context, agent); for (IArtifactRequest[] requests : artifactRequests) { - dm.add(requests); + for (int i = 0; i < requests.length; i++) { + dm.add(requests[i]); + totalArtifactRequests.add(requests[i]); + } + } + IProvisioningEventBus bus = (IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME); + if (bus != null) + bus.publishEvent(new CollectEvent(CollectEvent.TYPE_OVERALL_START, null, context, totalArtifactRequests.toArray(new IArtifactRequest[totalArtifactRequests.size()]))); + IStatus downloadStatus = dm.start(monitor); + try { + return downloadStatus; + } finally { + if (downloadStatus.isOK() && bus != null) + bus.publishEvent(new CollectEvent(CollectEvent.TYPE_OVERALL_END, null, context, totalArtifactRequests.toArray(new IArtifactRequest[totalArtifactRequests.size()]))); } - return dm.start(monitor); } protected IStatus initializePhase(IProgressMonitor monitor, IProfile profile, Map<String, Object> parameters) { diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Configure.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Configure.java index 7d4a834ef..f7fc7c871 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Configure.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Configure.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -7,23 +7,68 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Wind River - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.engine.phases; -import org.eclipse.equinox.p2.query.QueryUtil; - import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.equinox.internal.p2.engine.*; -import org.eclipse.equinox.p2.engine.PhaseSetFactory; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; +import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.engine.PhaseSetFactory; import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; +import org.eclipse.equinox.p2.engine.spi.Touchpoint; import org.eclipse.equinox.p2.metadata.IArtifactKey; import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.osgi.util.NLS; public class Configure extends InstallableUnitPhase { + final static class BeforeConfigureEventAction extends ProvisioningAction { + + public IStatus execute(Map<String, Object> parameters) { + IProfile profile = (IProfile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, true, profile, iu, InstallableUnitEvent.CONFIGURE, getTouchpoint())); + return null; + } + + public IStatus undo(Map<String, Object> parameters) { + Profile profile = (Profile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, false, profile, iu, InstallableUnitEvent.UNCONFIGURE, getTouchpoint())); + return null; + } + } + + final static class AfterConfigureEventAction extends ProvisioningAction { + + public IStatus execute(Map<String, Object> parameters) { + Profile profile = (Profile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, false, profile, iu, InstallableUnitEvent.CONFIGURE, getTouchpoint())); + return null; + } + + public IStatus undo(Map<String, Object> parameters) { + IProfile profile = (IProfile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, true, profile, iu, InstallableUnitEvent.UNCONFIGURE, getTouchpoint())); + return null; + } + } + public Configure(int weight) { super(PhaseSetFactory.PHASE_CONFIGURE, weight); } @@ -34,9 +79,23 @@ public class Configure extends InstallableUnitPhase { protected List<ProvisioningAction> getActions(InstallableUnitOperand currentOperand) { IInstallableUnit unit = currentOperand.second(); - if (QueryUtil.isFragment(unit)) - return null; - return getActions(unit, phaseId); + + ProvisioningAction beforeAction = new BeforeConfigureEventAction(); + ProvisioningAction afterAction = new AfterConfigureEventAction(); + Touchpoint touchpoint = getActionManager().getTouchpointPoint(unit.getTouchpointType()); + if (touchpoint != null) { + beforeAction.setTouchpoint(touchpoint); + afterAction.setTouchpoint(touchpoint); + } + ArrayList<ProvisioningAction> actions = new ArrayList<ProvisioningAction>(); + actions.add(beforeAction); + if (!QueryUtil.isFragment(unit)) { + List<ProvisioningAction> parsedActions = getActions(unit, phaseId); + if (parsedActions != null) + actions.addAll(parsedActions); + } + actions.add(afterAction); + return actions; } protected String getProblemMessage() { diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Unconfigure.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Unconfigure.java index 8edd542f5..76a8d6341 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Unconfigure.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Unconfigure.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -7,22 +7,67 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Wind River - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.engine.phases; -import org.eclipse.equinox.p2.query.QueryUtil; - import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.equinox.internal.p2.engine.*; -import org.eclipse.equinox.p2.engine.PhaseSetFactory; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; +import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.engine.PhaseSetFactory; import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; +import org.eclipse.equinox.p2.engine.spi.Touchpoint; import org.eclipse.equinox.p2.metadata.IArtifactKey; import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.query.QueryUtil; public class Unconfigure extends InstallableUnitPhase { + final static class BeforeUnConfigureEventAction extends ProvisioningAction { + + public IStatus execute(Map<String, Object> parameters) { + IProfile profile = (IProfile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, true, profile, iu, InstallableUnitEvent.UNCONFIGURE, getTouchpoint())); + return null; + } + + public IStatus undo(Map<String, Object> parameters) { + Profile profile = (Profile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, false, profile, iu, InstallableUnitEvent.CONFIGURE, getTouchpoint())); + return null; + } + } + + final static class AfterUnConfigureEventAction extends ProvisioningAction { + + public IStatus execute(Map<String, Object> parameters) { + Profile profile = (Profile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, false, profile, iu, InstallableUnitEvent.UNCONFIGURE, getTouchpoint())); + return null; + } + + public IStatus undo(Map<String, Object> parameters) { + IProfile profile = (IProfile) parameters.get(PARM_PROFILE); + String phaseId = (String) parameters.get(PARM_PHASE_ID); + IInstallableUnit iu = (IInstallableUnit) parameters.get(PARM_IU); + IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); + ((IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME)).publishEvent(new InstallableUnitEvent(phaseId, true, profile, iu, InstallableUnitEvent.CONFIGURE, getTouchpoint())); + return null; + } + } + public Unconfigure(int weight, boolean forced) { super(PhaseSetFactory.PHASE_UNCONFIGURE, weight, forced); } @@ -39,10 +84,23 @@ public class Unconfigure extends InstallableUnitPhase { //TODO: monitor.subTask(NLS.bind(Messages.Engine_Unconfiguring_IU, unit.getId())); IInstallableUnit unit = currentOperand.first(); - if (QueryUtil.isFragment(unit)) - return null; - return getActions(unit, phaseId); + ProvisioningAction beforeAction = new BeforeUnConfigureEventAction(); + ProvisioningAction afterAction = new AfterUnConfigureEventAction(); + Touchpoint touchpoint = getActionManager().getTouchpointPoint(unit.getTouchpointType()); + if (touchpoint != null) { + beforeAction.setTouchpoint(touchpoint); + afterAction.setTouchpoint(touchpoint); + } + ArrayList<ProvisioningAction> actions = new ArrayList<ProvisioningAction>(); + actions.add(beforeAction); + if (!QueryUtil.isFragment(unit)) { + List<ProvisioningAction> parsedActions = getActions(unit, phaseId); + if (parsedActions != null) + actions.addAll(parsedActions); + } + actions.add(afterAction); + return actions; } protected String getProblemMessage() { diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadProgressEvent.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadProgressEvent.java new file mode 100644 index 000000000..fdc1b7c39 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadProgressEvent.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River 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: + * Wind River - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.repository; + +import java.net.URI; +import java.util.EventObject; + +public class DownloadProgressEvent extends EventObject { + + private static final long serialVersionUID = -7880532297074721824L; + private ProgressStatistics stat; + + public DownloadProgressEvent(ProgressStatistics stat) { + super(stat); + this.stat = stat; + } + + public String getFileName() { + return stat.m_fileName; + } + + public URI getDownloadURI() { + return stat.m_uri; + } + + public long getAverageSpeed() { + return stat.getAverageSpeed(); + } + + public long getRecentSpeed() { + return stat.getRecentSpeed(); + } + + public long getFinished() { + return stat.m_current; + } + + public double getPercentage() { + return stat.getPercentage(); + } +} diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadStatus.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadStatus.java index de0597da7..ddcccb7ba 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadStatus.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/DownloadStatus.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 IBM Corporation and others. + * Copyright (c) 2008, 2012 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 @@ -74,4 +74,19 @@ public class DownloadStatus extends Status { public long getLastModified() { return lastModified; } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(super.toString()); + sb.append(' '); + sb.append("LastModified="); //$NON-NLS-1$ + sb.append(getLastModified()); + sb.append(' '); + sb.append("FileSize="); //$NON-NLS-1$ + sb.append(getFileSize() == UNKNOWN_SIZE ? "Unknown size" : getFileSize()); //$NON-NLS-1$ + sb.append(' '); + sb.append("Download rate="); //$NON-NLS-1$ + sb.append(getTransferRate() == UNKNOWN_RATE ? "Unknown rate" : getTransferRate()); //$NON-NLS-1$ + return sb.toString(); + } } diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/ProgressStatistics.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/ProgressStatistics.java index 6169fb36d..dd8c89a89 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/ProgressStatistics.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/ProgressStatistics.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 Cloudsmith Inc. + * Copyright (c) 2006, 2012 Cloudsmith Inc. * 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 @@ -16,6 +16,9 @@ import java.net.URI; import java.text.NumberFormat; import java.util.SortedMap; import java.util.TreeMap; +import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; +import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.osgi.util.NLS; /** @@ -30,6 +33,8 @@ public class ProgressStatistics { private static final int SPEED_RESOLUTION = 1000; + private static IProvisioningAgent agent = null; + private static String convert(long amount) { NumberFormat fmt = NumberFormat.getInstance(); if (amount < 1024) @@ -42,13 +47,27 @@ public class ProgressStatistics { return fmt.format(((double) amount) / (1024 * 1024)) + "MB"; //$NON-NLS-1$ } - private final String m_fileName; + public static void setProvisioningAgent(IProvisioningAgent agent) { + ProgressStatistics.agent = agent; + } + + private void publishEvent(DownloadProgressEvent event) { + if (agent == null) { + agent = ServiceHelper.getService(Activator.getContext(), IProvisioningAgent.class); + } + IProvisioningEventBus eventBus = (IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME); + if (eventBus != null) { + eventBus.publishEvent(event); + } + } + + final String m_fileName; private final long m_total; private final long m_startTime; - private long m_current; + long m_current; private long m_lastReportTime; @@ -58,7 +77,7 @@ public class ProgressStatistics { private long m_recentSpeedMapKey; - private URI m_uri; + URI m_uri; public ProgressStatistics(URI uri, String fileName, long total) { m_startTime = System.currentTimeMillis(); @@ -125,6 +144,11 @@ public class ProgressStatistics { } public synchronized String report() { + publishEvent(new DownloadProgressEvent(this)); + return createReportString(); + } + + private String createReportString() { String uriString = m_uri.toString(); if (m_fileName != null && uriString.endsWith(m_fileName)) uriString = uriString.substring(0, uriString.lastIndexOf(m_fileName)); @@ -145,7 +169,7 @@ public class ProgressStatistics { } public String toString() { - return report(); + return createReportString(); } synchronized private void registerRecentSpeed(long key, long inc) { diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/AllTests.java index e5c9aae63..69100ff0b 100644 --- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/AllTests.java +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/AllTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 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 @@ -36,6 +36,7 @@ public class AllTests extends TestCase { suite.addTestSuite(ActionManagerTest.class); suite.addTestSuite(TouchpointManagerTest.class); suite.addTestSuite(TouchpointTest.class); + suite.addTestSuite(ProvisioningEventTest.class); return suite; } diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/ProvisioningEventTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/ProvisioningEventTest.java new file mode 100644 index 000000000..8385e5273 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/ProvisioningEventTest.java @@ -0,0 +1,283 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River 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: + * Wind River - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests.engine; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.net.URI; +import java.util.*; +import org.eclipse.core.internal.registry.ExtensionRegistry; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.spi.RegistryContributor; +import org.eclipse.equinox.internal.p2.artifact.repository.MirrorEvent; +import org.eclipse.equinox.internal.p2.engine.*; +import org.eclipse.equinox.internal.p2.metadata.TouchpointData; +import org.eclipse.equinox.internal.p2.metadata.TouchpointInstruction; +import org.eclipse.equinox.internal.provisional.p2.core.eventbus.ProvisioningListener; +import org.eclipse.equinox.p2.core.ProvisionException; +import org.eclipse.equinox.p2.engine.*; +import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; +import org.eclipse.equinox.p2.metadata.*; +import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.QueryUtil; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRequest; +import org.eclipse.equinox.p2.tests.AbstractProvisioningTest; +import org.eclipse.equinox.p2.tests.TestActivator; +import org.junit.*; + +public class ProvisioningEventTest extends AbstractProvisioningTest { + private IEngine engine; + private File testProvisioning; + + @Before + public void setUp() throws Exception { + engine = getEngine(); + testProvisioning = new File(System.getProperty("java.io.tmpdir"), "testProvisioning"); + delete(testProvisioning); + testProvisioning.mkdir(); + } + + @After + public void tearDown() throws Exception { + engine = null; + delete(testProvisioning); + } + + @Test + public void testCollectEvent() throws ProvisionException, OperationCanceledException { + class ProvTestListener implements ProvisioningListener { + int requestsNumber = 0; + boolean called = false; + boolean mirrorEevent = false; + + public void notify(EventObject o) { + if (o instanceof CollectEvent) { + if (((CollectEvent) o).getType() == CollectEvent.TYPE_OVERALL_START && ((CollectEvent) o).getRepository() == null) { + called = true; + IArtifactRequest[] requests = ((CollectEvent) o).getDownloadRequests(); + requestsNumber = requests.length; + } + } else if (o instanceof MirrorEvent) { + mirrorEevent = true; + System.out.println(((MirrorEvent) o).getDownloadStatus()); + } + } + } + final ProvTestListener listener = new ProvTestListener(); + getEventBus().addListener(listener); + try { + URI repoLoc = getTestData("Load test data.", "/testData/testRepos/updateSite").toURI(); + IProfile profile = createProfile("test"); + ProvisioningContext context = new ProvisioningContext(getAgent()); + context.setArtifactRepositories(new URI[] {repoLoc}); + context.setMetadataRepositories(new URI[] {repoLoc}); + IProvisioningPlan plan = engine.createPlan(profile, context); + IQueryResult<IInstallableUnit> allIUs = getMetadataRepositoryManager().loadRepository(repoLoc, null).query(QueryUtil.ALL_UNITS, null); + for (IInstallableUnit iu : allIUs.toSet()) { + plan.addInstallableUnit(iu); + } + IStatus status = engine.perform(plan, new NullProgressMonitor()); + assertTrue("Provisioning was failed.", status.isOK()); + assertTrue("Collect event wasn't dispatched.", listener.called); + assertEquals("Collect event didn't report expected artifacts to be downloaded.", 19, listener.requestsNumber); + assertTrue("Mirror event wasn't dispatched.", listener.mirrorEevent); + } finally { + getEventBus().removeListener(listener); + } + } + + @Test + public void testPhaseEvent() throws ProvisionException, OperationCanceledException { + final String[] phaseSets = new String[] {PhaseSetFactory.PHASE_COLLECT, PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_INSTALL, PhaseSetFactory.PHASE_CONFIGURE}; + + class ProvTestListener implements ProvisioningListener { + String publishUnWantedPhaseEvent = null; + int publishUnWantedPhaseType = 0; + List<String> phaseStartEventToBePublised = new ArrayList<String>(Arrays.asList(phaseSets)); + List<String> phaseEndEventToBePublised = new ArrayList<String>(Arrays.asList(phaseSets)); + + public void notify(EventObject o) { + if (o instanceof PhaseEvent) { + PhaseEvent event = (PhaseEvent) o; + if (event.getType() == PhaseEvent.TYPE_START) { + if (!phaseStartEventToBePublised.remove(event.getPhaseId())) + publishUnWantedPhaseEvent = event.getPhaseId(); + } else if (event.getType() == PhaseEvent.TYPE_END) { + if (!phaseEndEventToBePublised.remove(event.getPhaseId())) + publishUnWantedPhaseEvent = event.getPhaseId(); + } else + publishUnWantedPhaseType = event.getType(); + } + } + } + final ProvTestListener listener = new ProvTestListener(); + getEventBus().addListener(listener); + try { + URI repoLoc = getTestData("Load test data.", "/testData/testRepos/updateSite").toURI(); + IProfile profile = createProfile("test"); + ProvisioningContext context = new ProvisioningContext(getAgent()); + context.setArtifactRepositories(new URI[] {repoLoc}); + context.setMetadataRepositories(new URI[] {repoLoc}); + IProvisioningPlan plan = engine.createPlan(profile, context); + IQueryResult<IInstallableUnit> allIUs = getMetadataRepositoryManager().loadRepository(repoLoc, null).query(QueryUtil.ALL_UNITS, null); + for (IInstallableUnit iu : allIUs.toSet()) { + plan.addInstallableUnit(iu); + } + IStatus status = engine.perform(plan, PhaseSetFactory.createPhaseSetIncluding(phaseSets), new NullProgressMonitor()); + assertTrue("Provisioning was failed.", status.isOK()); + assertNull("Published phase event with unwanted phase id.", listener.publishUnWantedPhaseEvent); + assertEquals("Published unwanted type of phase event.", 0, listener.publishUnWantedPhaseType); + assertEquals("Expected Phase start event is not published.", new ArrayList<String>(0), listener.phaseStartEventToBePublised); + assertEquals("Expected Phase end event is not published.", new ArrayList<String>(0), listener.phaseEndEventToBePublised); + } finally { + getEventBus().removeListener(listener); + } + } + + @Test + public void testConfigureUnConfigureEvent() { + final String iuId = "test"; + class ProvTestListener implements ProvisioningListener { + int preConfigureEvent = 0; + int postConfigureEvent = 0; + int preUnConfigureEvent = 0; + int postUnConfigureEvent = 0; + + public void notify(EventObject o) { + if (o instanceof InstallableUnitEvent) { + InstallableUnitEvent event = (InstallableUnitEvent) o; + if (event.getPhase().equals(PhaseSetFactory.PHASE_CONFIGURE) && event.isConfigure() && event.getInstallableUnit().getId().equals(iuId)) { + if (event.isPre()) + preConfigureEvent++; + else if (event.isPost()) + postConfigureEvent++; + } else if (event.getPhase().equals(PhaseSetFactory.PHASE_UNCONFIGURE) && event.isUnConfigure() && event.getInstallableUnit().getId().equals(iuId)) { + if (event.isPre()) + preUnConfigureEvent++; + else if (event.isPost()) + postUnConfigureEvent++; + } + } + } + } + final ProvTestListener listener = new ProvTestListener(); + getEventBus().addListener(listener); + + try { + IProfile profile = createProfile("testConfigureEvent"); + IProvisioningPlan plan = engine.createPlan(profile, null); + Map<String, ITouchpointInstruction> data = new HashMap<String, ITouchpointInstruction>(); + Map<String, String> parameters = new HashMap<String, String>(); + parameters.put("location", "http://download.eclipse.org/releases/juno"); + parameters.put("type", "1"); + parameters.put("name", "Juno"); + parameters.put("enabled", "true"); + data.put(PhaseSetFactory.PHASE_CONFIGURE, new TouchpointInstruction(TouchpointInstruction.encodeAction("addRepository", parameters), null)); + IInstallableUnit testIU = createResolvedIU(createEclipseIU(iuId, Version.create("1.0.0"), new IRequirement[0], new TouchpointData(data))); + plan.addInstallableUnit(testIU); + IStatus result = engine.perform(plan, PhaseSetFactory.createDefaultPhaseSet(), new NullProgressMonitor()); + assertTrue("0.2", result.isOK()); + Set<IInstallableUnit> installedIUs = profile.available(QueryUtil.ALL_UNITS, null).toUnmodifiableSet(); + assertEquals("0.3", 1, installedIUs.size()); + plan = engine.createPlan(profile, null); + plan.removeInstallableUnit(testIU); + result = engine.perform(plan, PhaseSetFactory.createDefaultPhaseSet(), new NullProgressMonitor()); + assertTrue("0.4", result.isOK()); + assertEquals("0.5", 1, listener.preConfigureEvent); + assertEquals("0.6", 1, listener.postConfigureEvent); + assertEquals("0.7", 1, listener.preUnConfigureEvent); + assertEquals("0.8", 1, listener.postUnConfigureEvent); + } finally { + getEventBus().removeListener(listener); + } + } + + public static class AlwaysFail extends ProvisioningAction { + + @Override + public IStatus execute(Map<String, Object> parameters) { + int a = 1; + if (a == 1) + throw new NullPointerException("no reason"); + return null; + } + + @Override + public IStatus undo(Map<String, Object> parameters) { + return null; + } + + } + + @Test + public void testConfigureUndoEvent() { + final String iuId = "test"; + final String failureIU = "alwaysFail"; + class ProvTestListener implements ProvisioningListener { + int preConfigureEvent = 0; + int postConfigureEvent = 0; + int preUnConfigureEventForUndo = 0; + int postUnConfigureEventForUndo = 0; + + public void notify(EventObject o) { + if (o instanceof InstallableUnitEvent) { + InstallableUnitEvent event = (InstallableUnitEvent) o; + if (event.getPhase().equals(PhaseSetFactory.PHASE_CONFIGURE) && event.getInstallableUnit().getId().equals(iuId)) { + if (event.isConfigure() && event.isPre()) + preConfigureEvent++; + else if (event.isConfigure() && event.isPost()) + postConfigureEvent++; + else if (event.isUnConfigure() && event.isPre()) + preUnConfigureEventForUndo++; + else if (event.isUnConfigure() && event.isPost()) + postUnConfigureEventForUndo++; + } else if (event.getPhase().equals(PhaseSetFactory.PHASE_CONFIGURE) && event.getInstallableUnit().getId().equals(failureIU)) { + if (event.isConfigure() && event.isPre()) { + preConfigureEvent++; + } else if (event.isConfigure() && event.isPost()) + postConfigureEvent++; + else if (event.isUnConfigure() && event.isPre()) + preUnConfigureEventForUndo++; + else if (event.isUnConfigure() && event.isPost()) + postUnConfigureEventForUndo++; + } + } + } + } + final ProvTestListener listener = new ProvTestListener(); + getEventBus().addListener(listener); + + try { + final String customTouchPoint = "<extension point=\"org.eclipse.equinox.p2.engine.actions\"> <action class=\"org.eclipse.equinox.p2.tests.engine.ProvisioningEventTest.AlwaysFail\" name=\"alwaysFail\" touchpointType=\"org.eclipse.equinox.p2.osgi\" touchpointVersion=\"1.0.0\" version=\"1.0.0\"></action></extension>"; + ByteArrayInputStream input = new ByteArrayInputStream(customTouchPoint.getBytes()); + IExtensionRegistry registry = Platform.getExtensionRegistry(); + registry.addContribution(input, new RegistryContributor(TestActivator.PI_PROV_TESTS, "p2 tests", null, null), false, "Always Fail TouchPoint Action", null, ((ExtensionRegistry) registry).getTemporaryUserToken()); + + IProfile profile = createProfile("testConfigureEvent"); + IProvisioningPlan plan = engine.createPlan(profile, null); + Map<String, ITouchpointInstruction> data = new HashMap<String, ITouchpointInstruction>(); + data.put(PhaseSetFactory.PHASE_CONFIGURE, MetadataFactory.createTouchpointInstruction("instructionparsertest.goodAction()", null)); + IInstallableUnit testIU = createResolvedIU(createIU(iuId, Version.create("1.0.0"), null, new IRequirement[0], BUNDLE_CAPABILITY, NO_PROPERTIES, ITouchpointType.NONE, new TouchpointData(data), false)); + plan.addInstallableUnit(testIU); + data = new HashMap<String, ITouchpointInstruction>(1); + data.put(PhaseSetFactory.PHASE_CONFIGURE, new TouchpointInstruction("alwaysFail();", null)); + plan.addInstallableUnit(createResolvedIU(createEclipseIU(failureIU, Version.create("1.0.0"), new IRequirement[0], new TouchpointData(data)))); + IStatus result = engine.perform(plan, PhaseSetFactory.createDefaultPhaseSet(), new NullProgressMonitor()); + assertFalse(result.isOK()); + assertEquals("0.5", 2, listener.preConfigureEvent); + assertEquals("0.6", 1, listener.postConfigureEvent); + assertEquals("0.7", 1, listener.preUnConfigureEventForUndo); + assertEquals("0.8", 2, listener.postUnConfigureEventForUndo); + } finally { + getEventBus().removeListener(listener); + } + } +} |