From b86b21139a5367412cd51e86d359af33b0c03c3c Mon Sep 17 00:00:00 2001 From: Pascal Rapicault (Ericsson) Date: Sun, 27 Jan 2013 23:41:19 -0500 Subject: Squashed commit of the following: 304132 - [shared] upgrading shared base causes loss of user installer plug-ins commit 8461eae803454c36f6a18013c44e37c20810d141 Merge: 23bc40c c847dee Author: Pascal Rapicault Date: Sun Jan 27 22:11:45 2013 -0500 Merge branch 'master' into prapicau/sharedInstall-part1 commit 23bc40c4f85b01f37fb0ac23992524a7c8ccd892 Author: Pascal Rapicault (Ericsson) Date: Sun Jan 27 21:38:07 2013 -0500 Use constant and fix copyright header commit bc11d565b32b5b5c8bb5c93e5ea666b1d06b43ff Author: Pascal Rapicault (Ericsson) Date: Sun Jan 27 21:33:32 2013 -0500 Annotate new profile with a base profile timestamp commit ba4e7abda6e44ad47aead2fade320f9be08b27d5 Author: Pascal Rapicault (Ericsson) Date: Sun Jan 27 21:32:20 2013 -0500 Add constants commit 54c8d356527d1321e25bd837e674b758aa61e248 Author: Krzysztof Daniel Date: Thu Jan 24 13:23:15 2013 +0100 SimpleConfiguratorImpl refactoring and tests. commit 6177c466083fb7676ebfe5790bc0951043b3b727 Author: Pascal Rapicault (Ericsson) Date: Thu Jan 24 11:59:45 2013 -0500 detection of change in the reconciler commit f04f46d6d283a6235367872b5eaa7e3e483509ed Merge: 5243d49 c32f111 Author: Pascal Rapicault Date: Thu Jan 24 11:43:01 2013 -0500 Merge branch 'master' into prapicau/sharedInstall-part1 commit 5243d497142b0f2631bcda8b5fed67d7ce0ddbd5 Author: Pascal Rapicault Date: Wed Jan 23 15:26:41 2013 -0500 always use shared install when the ignoreUserConfig property is set commit 12eccdad23420e7ba91f99221c852f7e32eb11de Merge: c68f394 1e9fc23 Author: Pascal Rapicault Date: Wed Jan 23 10:29:56 2013 -0500 Merge branch 'master' into prapicau/sharedInstall-part1 commit c68f394a39c4215ed7ac960495a3c59eb3cf3eee Author: Pascal Rapicault Date: Tue Jan 22 22:24:04 2013 -0500 Bug 398853 - [UI] installed IU shows as update commit aa6d632dea7ff54e9ba7c3c7f9f2ecd30afe5906 Author: Pascal Rapicault Date: Tue Jan 22 13:50:05 2013 -0500 Differentiate initial profile creation from reset. commit 4fb3429ed3fd673d5daf7ca1ce9bf1184a0afcb3 Author: Pascal Rapicault Date: Tue Jan 22 13:49:23 2013 -0500 Only show migration dialog once commit a34eac29e330a41991d003e2dcd2d8b264d77145 Author: Krzysztof Daniel Date: Mon Jan 21 12:40:36 2013 +0100 397216: [Shared] Better shared configuration change discovery Perform dropins reindexing after master configuration had been changed. https://bugs.eclipse.org/bugs/show_bug.cgi?id=397216 commit 6981ca8bd3c1db9ab2dd9484a1f7c8950fcd1abe Merge: dfec14b 33ca260 Author: Pascal Rapicault Date: Mon Jan 21 15:04:28 2013 -0500 Merge branch 'master' into prapicau/sharedInstall-part1 commit dfec14b67a69b6fa14efb860ef8a986053a58917 Merge: 6067d05 ba5f048 Author: Pascal Rapicault Date: Mon Jan 21 11:34:38 2013 -0500 Merge branch 'master' into prapicau/sharedInstall-part1 commit ba5f048a3ac5563430104adeb173dc4f7dda6eca Author: Pascal Rapicault Date: Mon Jan 21 11:28:20 2013 -0500 Bug 398539 - Got a NPE trying to add a new update site commit 6067d05e402fe796debd9d25604cae7026df5b48 Author: Pascal Rapicault Date: Fri Jan 18 16:16:18 2013 -0500 only write timestamp file for shared install commit 8ab9410d8c797e6a8d2a97e4ba46da3d548440fa Author: Pascal Rapicault (Ericsson) Date: Fri Jan 18 13:56:46 2013 -0500 Cache the fact that the state.properties is missing commit fefbc5bdec2ce6cdb7fd71b1790bf8abdee8737a Author: Pascal Rapicault (Ericsson) Date: Fri Jan 18 13:51:54 2013 -0500 Fix bug in change detection logic commit 3de6f8593d5c1b21be3bd21000e34acb945056b1 Author: Pascal Rapicault (Ericsson) Date: Wed Jan 16 19:50:32 2013 -0500 Detect changes in the bundles.info commit 446649c95063dca689f4d2c886b26975a11f3499 Author: Pascal Rapicault Date: Tue Jan 15 14:04:57 2013 -0500 Simple notification to let the user know that the base has changed. commit e004dc5270abd33a60da9a8d0340409bc8e4a38d Author: Pascal Rapicault Date: Fri Jan 11 14:15:20 2013 +0100 ignore user config.ini if out of sync with base commit a0235c0c95b9047e64d6e24c9d8f6b8588087113 Author: Pascal Rapicault (Ericsson) Date: Wed Dec 12 09:57:36 2012 -0500 Obtain specific profile state properties without locking commit 1d0f129ca70716e7a181631e1ba0e71f16e35e08 Author: Pascal Rapicault (Ericsson) Date: Mon Dec 10 16:06:38 2012 -0500 Remember the timestamp of the base config.ini commit 3134caecfd244fd88386f3ce4bd1a6fc71fe8007 Author: Pascal Rapicault (Ericsson) Date: Wed Dec 5 16:21:50 2012 -0500 Support to ignore the existing profile if the base has changed commit 7f0ba4e643f40bc0143617b93b2238388d38216d Author: Pascal Rapicault (Ericsson) Date: Tue Dec 4 11:23:37 2012 -0500 Remove externalization warning --- .../internal/p2/engine/SimpleProfileRegistry.java | 144 ++++++++++++++++----- .../org/eclipse/equinox/p2/engine/IProfile.java | 24 ++++ .../equinox/p2/engine/IProfileRegistry.java | 5 +- 3 files changed, 139 insertions(+), 34 deletions(-) (limited to 'bundles/org.eclipse.equinox.p2.engine/src') 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 945ec048e..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 @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 IBM Corporation and others. All rights reserved. This + * 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 http://www.eclipse.org/legal/epl-v10.html * * 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$ @@ -168,7 +170,7 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } public synchronized String toString() { - return "Profile registry for location: " + store.getAbsolutePath() + "\n" + getProfileMap().toString(); //$NON-NLS-1$ + return "Profile registry for location: " + store.getAbsolutePath() + "\n" + getProfileMap().toString(); //$NON-NLS-1$ //$NON-NLS-2$ } public synchronized IProfile getProfile(String id) { @@ -243,12 +245,57 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { if (SELF.equals(id)) id = self; Profile profile = getProfileMap().get(id); - if (profile == null && self != null && self.equals(id)) - profile = createSurrogateProfile(id); - + if (self != null && self.equals(id)) { + boolean resetProfile = false; + if (profile != null && ignoreExistingProfile(profile)) { + 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) { + //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 (!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; + } + + 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) { if (surrogateProfileHandler == null) return null; @@ -294,7 +341,7 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { public synchronized void updateProfile(Profile profile) { String id = profile.getProfileId(); - Profile current = internalGetProfile(id); + Profile current = getProfileMap().get(id); if (current == null) throw new IllegalArgumentException(NLS.bind(Messages.profile_does_not_exist, id)); @@ -730,7 +777,7 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } public synchronized boolean isCurrent(IProfile profile) { - Profile internalProfile = internalGetProfile(profile.getProfileId()); + Profile internalProfile = getProfileMap().get(profile.getProfileId()); if (internalProfile == null) throw new IllegalArgumentException(NLS.bind(Messages.profile_not_registered, profile.getProfileId())); @@ -833,10 +880,9 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } public synchronized void unlockProfile(IProfile profile) { - Profile internalProfile = internalGetProfile(profile.getProfileId()); - if (internalProfile == null) + if (profile == null) throw new IllegalArgumentException(NLS.bind(Messages.profile_not_registered, profile.getProfileId())); - internalUnlockProfile(internalProfile); + internalUnlockProfile(profile); } private void internalUnlockProfile(IProfile profile) { @@ -897,6 +943,8 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { // return true if the cached timestamp is the same as the one on disk boolean isCurrent() { + if (!file.exists()) + return true; return file.lastModified() == timestamp; } @@ -936,8 +984,10 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { File file = new File(profileDirectory, PROFILE_PROPERTIES_FILE); Properties properties = new Properties(); - if (!file.exists()) + if (!file.exists()) { + lastAccessedProperties = new ProfileStateProperties(id, file, properties); return properties; + } InputStream input = null; try { input = new BufferedInputStream(new FileInputStream(file)); @@ -1032,22 +1082,30 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { public IStatus setProfileStateProperties(String id, long timestamp, Map propertiesToAdd) { if (id == null || propertiesToAdd == null) throw new NullPointerException(); - IStatus result = validateState(id, timestamp); + + Profile internalProfile = internalGetProfile(id); + return internalSetProfileStateProperties(internalProfile, timestamp, propertiesToAdd); + } + + private IStatus internalSetProfileStateProperties(IProfile profile, long timestamp, Map propertiesToAdd) { + IStatus result = validateState(profile.getProfileId(), timestamp); if (!result.isOK()) return result; - Profile internalProfile = internalGetProfile(id); - lockProfile(internalProfile); + + if (!internalLockProfile(profile)) + throw new IllegalStateException(Messages.SimpleProfileRegistry_Profile_in_use); + try { - Properties properties = readStateProperties(id); + Properties properties = readStateProperties(profile.getProfileId()); for (Map.Entry entry : propertiesToAdd.entrySet()) { // property key format is timestamp.key properties.put(timestamp + "." + entry.getKey(), entry.getValue()); //$NON-NLS-1$ } - writeStateProperties(id, properties); + writeStateProperties(profile.getProfileId(), properties); } catch (ProvisionException e) { return e.getStatus(); } finally { - unlockProfile(internalProfile); + internalUnlockProfile(profile); } return Status.OK_STATUS; } @@ -1056,27 +1114,36 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { * @see org.eclipse.equinox.p2.engine.IProfileRegistry#setProfileStateProperty(java.lang.String, long, java.lang.String, java.lang.String) */ public IStatus setProfileStateProperty(String id, long timestamp, String key, String value) { - if (id == null || key == null || value == null) + if (id == null) + throw new NullPointerException(); + return internalSetProfileStateProperty(internalGetProfile(id), timestamp, key, value); + } + + private IStatus internalSetProfileStateProperty(IProfile profile, long timestamp, String key, String value) { + if (key == null || value == null) throw new NullPointerException(); Map properties = new HashMap(); properties.put(key, value); - return setProfileStateProperties(id, timestamp, properties); + + return internalSetProfileStateProperties(profile, timestamp, properties); } - /* (non-Javadoc) - * @see org.eclipse.equinox.p2.engine.IProfileRegistry#getProfileStateProperties(java.lang.String, long) - */ public Map getProfileStateProperties(String id, long timestamp) { if (id == null) throw new NullPointerException(); + return internalGetProfileStateProperties(internalGetProfile(id), timestamp, true); + } + private Map internalGetProfileStateProperties(IProfile profile, long timestamp, boolean lock) { Map result = new HashMap(); String timestampString = String.valueOf(timestamp); int keyOffset = timestampString.length() + 1; - Profile internalProfile = internalGetProfile(id); - lockProfile(internalProfile); + lock = lock || lastAccessedProperties == null; + if (lock) + if (!internalLockProfile(profile)) + throw new IllegalStateException(Messages.SimpleProfileRegistry_Profile_in_use); try { - Properties properties = readStateProperties(id); + Properties properties = readStateProperties(profile.getProfileId()); Iterator keys = properties.keySet().iterator(); while (keys.hasNext()) { String key = (String) keys.next(); @@ -1086,7 +1153,8 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } catch (ProvisionException e) { LogHelper.log(e); } finally { - unlockProfile(internalProfile); + if (lock) + internalUnlockProfile(profile); } return result; } @@ -1098,11 +1166,18 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { if (id == null || userKey == null) throw new NullPointerException(); - Map result = new HashMap(); Profile internalProfile = internalGetProfile(id); - lockProfile(internalProfile); + return internalGetProfileStateProperties(internalProfile, userKey, true); + } + + private Map internalGetProfileStateProperties(IProfile profile, String userKey, boolean lock) { + Map result = new HashMap(); + lock = lock || lastAccessedProperties == null; + if (lock) + if (!internalLockProfile(profile)) + throw new IllegalStateException(Messages.SimpleProfileRegistry_Profile_in_use); try { - Properties properties = readStateProperties(id); + Properties properties = readStateProperties(profile.getProfileId()); Iterator keys = properties.keySet().iterator(); while (keys.hasNext()) { // property key format is timestamp.key @@ -1115,7 +1190,8 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } catch (ProvisionException e) { LogHelper.log(e); } finally { - unlockProfile(internalProfile); + if (lock) + internalUnlockProfile(profile); } return result; } @@ -1131,7 +1207,9 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { return Status.OK_STATUS; Profile internalProfile = internalGetProfile(id); - lockProfile(internalProfile); + if (!internalLockProfile(internalProfile)) + throw new IllegalStateException(Messages.SimpleProfileRegistry_Profile_in_use); + try { Properties properties = readStateProperties(id); String timestampString = String.valueOf(timestamp); @@ -1154,7 +1232,7 @@ public class SimpleProfileRegistry implements IProfileRegistry, IAgentService { } catch (ProvisionException e) { return e.getStatus(); } finally { - unlockProfile(internalProfile); + internalUnlockProfile(internalProfile); } return Status.OK_STATUS; } 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. -- cgit v1.2.3