From bc11d565b32b5b5c8bb5c93e5ea666b1d06b43ff Mon Sep 17 00:00:00 2001 From: Pascal Rapicault (Ericsson) Date: Sun, 27 Jan 2013 21:33:32 -0500 Subject: Annotate new profile with a base profile timestamp --- .../internal/p2/engine/SimpleProfileRegistry.java | 59 +++++++++++++++++----- .../org/eclipse/equinox/p2/engine/IProfile.java | 24 +++++++++ .../equinox/p2/engine/IProfileRegistry.java | 5 +- .../ui/sdk/scheduler/AutomaticUpdateScheduler.java | 21 ++++---- 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/SimpleProfileRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/SimpleProfileRegistry.java index e1367ea37..9e0265404 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/SimpleProfileRegistry.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/SimpleProfileRegistry.java @@ -6,7 +6,7 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Ericsson AB (Pascal Rapicault) - reading preferences from base in shared install + * Ericsson AB - ongoing development ******************************************************************************/ package org.eclipse.equinox.internal.p2.engine; @@ -38,6 +38,8 @@ import org.xml.sax.SAXException; public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { + private static final String SIMPLE_PROFILE_REGISTRY_INTERNAL = "_simpleProfileRegistry_internal_"; + private static final String ECLIPSE_IGNORE_USER_CONFIGURATION = "eclipse.ignoreUserConfiguration"; //$NON-NLS-1$ private static final String PROFILE_REGISTRY = "profile registry"; //$NON-NLS-1$ private static final String PROFILE_PROPERTIES_FILE = "state.properties"; //$NON-NLS-1$ @@ -246,25 +248,52 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { if (self != null && self.equals(id)) { boolean resetProfile = false; if (profile != null && ignoreExistingProfile(profile)) { - internalSetProfileStateProperty(profile, profile.getTimestamp(), "RESET", "RESET"); + internalSetProfileStateProperty(profile, profile.getTimestamp(), IProfile.STATE_PROP_SHARED_INSTALL, IProfile.STATE_SHARED_INSTALL_VALUE_BEFOREFLUSH); profile = null; resetProfile = true; } if (profile == null) { profile = createSurrogateProfile(id); - if (resetProfile) - internalSetProfileStateProperty(profile, profile.getTimestamp(), "NEW", "NEW"); - else - internalSetProfileStateProperty(profile, profile.getTimestamp(), "FIRST", "FIRST"); + if (resetProfile) { + //Now that we created a new profile. Tag it, override the property and register the timestamp in the agent registry for pickup by other + internalSetProfileStateProperty(profile, profile.getTimestamp(), IProfile.STATE_PROP_SHARED_INSTALL, IProfile.STATE_SHARED_INSTALL_VALUE_NEW); + internalSetProfileStateProperty(profile, profile.getTimestamp(), SIMPLE_PROFILE_REGISTRY_INTERNAL + getBaseTimestamp(profile.getProfileId()), getBaseTimestamp(id)); + System.setProperty(ECLIPSE_IGNORE_USER_CONFIGURATION, "profileFlushed"); //$NON-NLS-1$ + agent.registerService(SERVICE_SHARED_INSTALL_NEW_TIMESTAMP, Long.toString(profile.getTimestamp())); + } else { + //This is the first time we create the shared profile. Tag it as such and also remember the timestamp of the base + internalSetProfileStateProperty(profile, profile.getTimestamp(), IProfile.STATE_PROP_SHARED_INSTALL, IProfile.STATE_SHARED_INSTALL_VALUE_INITIAL); + internalSetProfileStateProperty(profile, profile.getTimestamp(), SIMPLE_PROFILE_REGISTRY_INTERNAL + getBaseTimestamp(profile.getProfileId()), getBaseTimestamp(id)); + } } } return profile; } private boolean ignoreExistingProfile(IProfile profile) { - if (internalGetProfileStateProperties(profile, profile.getTimestamp(), false).containsKey("NEW")) + if (!Boolean.TRUE.toString().equalsIgnoreCase(System.getProperty(ECLIPSE_IGNORE_USER_CONFIGURATION))) + return false; + + String baseTimestamp = getBaseTimestamp(profile.getProfileId()); + if (baseTimestamp == null) + return false; + + if (internalGetProfileStateProperties(profile, SIMPLE_PROFILE_REGISTRY_INTERNAL + baseTimestamp, false).size() != 0) return false; - return "true".equals(System.getProperty("eclipse.ignoreUserConfiguration")); + + return true; + } + + private String getBaseTimestamp(String id) { + IProvisioningAgent installer = (IProvisioningAgent) agent.getService(IProvisioningAgent.SHARED_BASE_AGENT); + if (installer == null) + return null; + IProfileRegistry registry = (IProfileRegistry) installer.getService(IProfileRegistry.SERVICE_NAME); + long[] revisions = registry.listProfileTimestamps(id); + if (revisions.length >= 1) { + return Long.toString(revisions[revisions.length - 1]); + } + return null; } private Profile createSurrogateProfile(String id) { @@ -310,7 +339,6 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { return result; } - // public synchronized void updateProfile(Profile profile) { String id = profile.getProfileId(); Profile current = getProfileMap().get(id); @@ -1139,13 +1167,15 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { throw new NullPointerException(); Profile internalProfile = internalGetProfile(id); - return internalGetProfileStateProperties(internalProfile, userKey); + return internalGetProfileStateProperties(internalProfile, userKey, true); } - private Map internalGetProfileStateProperties(IProfile profile, String userKey) { + private Map internalGetProfileStateProperties(IProfile profile, String userKey, boolean lock) { Map result = new HashMap(); - if (!internalLockProfile(profile)) - throw new IllegalStateException(Messages.SimpleProfileRegistry_Profile_in_use); + lock = lock || lastAccessedProperties == null; + if (lock) + if (!internalLockProfile(profile)) + throw new IllegalStateException(Messages.SimpleProfileRegistry_Profile_in_use); try { Properties properties = readStateProperties(profile.getProfileId()); Iterator keys = properties.keySet().iterator(); @@ -1160,7 +1190,8 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } catch (ProvisionException e) { LogHelper.log(e); } finally { - internalUnlockProfile(profile); + if (lock) + internalUnlockProfile(profile); } return result; } diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfile.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfile.java index 1f8de7645..7bd0060c2 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfile.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfile.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Ericsson AB - ongoing development *******************************************************************************/ package org.eclipse.equinox.p2.engine; @@ -145,6 +146,29 @@ public interface IProfile extends IQueryable { */ public static final String STATE_PROP_TAG = "org.eclipse.equinox.p2.state.tag"; //$NON-NLS-1$ + /** + * Profile state metadata property key used to represent the state of the user profile when running in shared install. + * The value for this property could be: {@value #STATE_PROP_INITIAL}, {@value #STATE_SHARED_INSTALL_VALUE_BEFOREFLUSH}, or {@value #STATE_SHARED_INSTALL_VALUE_NEW} + * @since 2.3 + */ + public static final String STATE_PROP_SHARED_INSTALL = "org.eclipse.equinox.p2.state.shared"; //$NON-NLS-1$ + + /** + * Value to represent a user profile the first time it is created. + * @since 2.3 + */ + public static final String STATE_SHARED_INSTALL_VALUE_INITIAL = "initial"; //$NON-NLS-1$ + /** + * Value to represent a user profile before it is being flushed because the base had changed. + * @since 2.3 + */ + public static final String STATE_SHARED_INSTALL_VALUE_BEFOREFLUSH = "beforeFlush"; //$NON-NLS-1$ + /** + * Value to represent the new user profile created once the base profile has been flushed. + * @since 2.3 + */ + public static final String STATE_SHARED_INSTALL_VALUE_NEW = "new"; //$NON-NLS-1$ + /** * Profile property constant for additional parameters of the downloading stats(e.g., package=jee&os=linux). * @since 2.2 diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfileRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfileRegistry.java index 381a61e20..b2490c894 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfileRegistry.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/IProfileRegistry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 IBM Corporation and others. + * Copyright (c) 2007, 2013 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,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Ericsson AB - ongoing development *******************************************************************************/ package org.eclipse.equinox.p2.engine; @@ -37,6 +38,8 @@ public interface IProfileRegistry { */ public static final String SERVICE_NAME = IProfileRegistry.class.getName(); + public static final String SERVICE_SHARED_INSTALL_NEW_TIMESTAMP = IProfileRegistry.class.getName() + '_' + "NEW_SELF_TIMESTAMP"; //$NON-NLS-1$ + /** * Return the profile in the registry that has the given id. If it does not exist, * then return null. diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java index 4923ed9a6..06186bb8b 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java +++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 IBM Corporation and others. + * Copyright (c) 2008, 2013 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,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Ericsson AB - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.ui.sdk.scheduler; @@ -94,28 +95,28 @@ public class AutomaticUpdateScheduler implements IStartup { } private boolean baseChanged() { - final String MIGRATION_DIALOG_SHOWN = "migrationDialogShown"; //$NON-NLS-1$ - if (!("true".equals(System.getProperty("eclipse.ignoreUserConfiguration")))) - return false; - IProvisioningAgent agent = (IProvisioningAgent) ServiceHelper.getService(AutomaticUpdatePlugin.getContext(), IProvisioningAgent.SERVICE_NAME); IProfileRegistry registry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); - IProfile currentProfile = registry.getProfile(profileId); - if (!"NEW".equals(registry.getProfileStateProperties(profileId, currentProfile.getTimestamp()).get("NEW"))) + //Access the running profile to force its reinitialization if it has not been done. + registry.getProfile(IProfileRegistry.SELF); + String resetState = (String) agent.getService(IProfileRegistry.SERVICE_SHARED_INSTALL_NEW_TIMESTAMP); + if (resetState == null) return false; + final String PREF_MIGRATION_DIALOG_SHOWN = "migrationDialogShown"; //$NON-NLS-1$ + //Have we already shown the migration dialog - if (AutomaticUpdatePlugin.getDefault().getPreferenceStore().getLong(MIGRATION_DIALOG_SHOWN) == currentProfile.getTimestamp()) + if (AutomaticUpdatePlugin.getDefault().getPreferenceStore().getString(PREF_MIGRATION_DIALOG_SHOWN) == resetState) return false; //Remember that we are showing the migration dialog - AutomaticUpdatePlugin.getDefault().getPreferenceStore().setValue(MIGRATION_DIALOG_SHOWN, currentProfile.getTimestamp()); + AutomaticUpdatePlugin.getDefault().getPreferenceStore().setValue(PREF_MIGRATION_DIALOG_SHOWN, resetState); AutomaticUpdatePlugin.getDefault().savePreferences(); Display d = Display.getDefault(); d.asyncExec(new Runnable() { public void run() { - MessageDialog.openWarning(getWorkbenchWindowShell(), "Installation modified", "An upgrade of the eclipse installation you are using has been performed. The plugins you had installed have been uninstalled."); + MessageDialog.openWarning(getWorkbenchWindowShell(), "Installation modified", "An upgrade of the eclipse installation you are using has been performed. The plugins you had installed have been uninstalled."); //$NON-NLS-1$ //$NON-NLS-2$ } }); return true; -- cgit v1.2.3