diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/ProfilePreferences.java')
-rw-r--r-- | bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/ProfilePreferences.java | 134 |
1 files changed, 94 insertions, 40 deletions
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/ProfilePreferences.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/ProfilePreferences.java index 8c84e4031..362f9f289 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/ProfilePreferences.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/ProfilePreferences.java @@ -17,10 +17,11 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.equinox.internal.p2.core.helpers.*; -import org.eclipse.equinox.internal.provisional.p2.core.location.AgentLocation; -import org.eclipse.equinox.internal.provisional.p2.engine.IProfileRegistry; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; +import org.eclipse.equinox.p2.core.IAgentLocation; +import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.engine.IProfileRegistry; +import org.eclipse.equinox.security.storage.EncodingUtils; +import org.osgi.framework.*; import org.osgi.service.prefs.BackingStoreException; /** @@ -50,7 +51,7 @@ public class ProfilePreferences extends EclipsePreferences { } // cache which nodes have been loaded from disk - private static Set loadedNodes = Collections.synchronizedSet(new HashSet()); + private static Set<String> loadedNodes = Collections.synchronizedSet(new HashSet<String>()); public static final Object PROFILE_SAVE_JOB_FAMILY = new Object(); @@ -69,25 +70,26 @@ public class ProfilePreferences extends EclipsePreferences { public ProfilePreferences(EclipsePreferences nodeParent, String nodeName) { super(nodeParent, nodeName); + //path is /profile/{agent location}/{profile id}/qualifier // cache the segment count String path = absolutePath(); segmentCount = getSegmentCount(path); - if (segmentCount <= 1) + if (segmentCount <= 2) return; - if (segmentCount == 2) + if (segmentCount == 3) profileLock = new Object(); - if (segmentCount < 3) + if (segmentCount < 4) return; // cache the qualifier - qualifier = getSegment(path, 2); + qualifier = getSegment(path, 3); } - private boolean containsProfile(String profileId) { - IProfileRegistry profileRegistry = (IProfileRegistry) ServiceHelper.getService(EngineActivator.getContext(), IProfileRegistry.class.getName()); + private boolean containsProfile(IProvisioningAgent agent, String profileId) { + IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); if (profileId == null || profileRegistry == null) return false; return profileRegistry.containsProfile(profileId); @@ -99,22 +101,68 @@ public class ProfilePreferences extends EclipsePreferences { */ protected void doSave() throws BackingStoreException { synchronized (((ProfilePreferences) parent).profileLock) { - String profileId = getSegment(absolutePath(), 1); - if (!containsProfile(profileId)) { - //use the default location for the self profile, otherwise just do nothing and return - if (IProfileRegistry.SELF.equals(profileId)) { - IPath location = getDefaultLocation(); - if (location != null) { - super.save(location); - return; + ServiceReference agentRef = getAgent(getSegment(absolutePath(), 1)); + IProvisioningAgent agent = (IProvisioningAgent) EngineActivator.getContext().getService(agentRef); + try { + String profileId = getSegment(absolutePath(), 2); + if (!containsProfile(agent, profileId)) { + //use the default location for the self profile, otherwise just do nothing and return + if (IProfileRegistry.SELF.equals(profileId)) { + IPath location = getDefaultLocation(); + if (location != null) { + super.save(location); + return; + } } + if (Tracing.DEBUG_PROFILE_PREFERENCES) + Tracing.debug("Not saving preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ + return; } - if (Tracing.DEBUG_PROFILE_PREFERENCES) - Tracing.debug("Not saving preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ - return; + super.save(getProfileLocation(agent, profileId)); + } finally { + EngineActivator.getContext().ungetService(agentRef); + } + } + } + + /** + * Returns a reference to the agent service corresponding to the given encoded + * agent location. Never returns null; throws an exception if the agent could not be found. + */ + private ServiceReference getAgent(String segment) throws BackingStoreException { + String locationString = EncodingUtils.decodeSlashes(segment); + Exception failure = null; + try { + String filter = "(locationURI=" + encodeForFilter(locationString) + ')'; //$NON-NLS-1$ + ServiceReference[] refs = EngineActivator.getContext().getServiceReferences(IProvisioningAgent.SERVICE_NAME, filter); + if (refs != null && refs.length > 0) + return refs[0]; + } catch (InvalidSyntaxException e) { + failure = e; + } + throw new BackingStoreException("Unable to determine provisioning agent from location: " + segment, failure); //$NON-NLS-1$ + } + + /** + * Encodes a string so that it is suitable for use as a value for a filter property. + * Any reserved filter characters are escaped. + */ + private String encodeForFilter(String string) { + StringBuffer result = new StringBuffer(string.length()); + char[] input = string.toCharArray(); + for (int i = 0; i < input.length; i++) { + switch (input[i]) { + case '(' : + case ')' : + case '*' : + case '\\' : + result.append('\\'); + //fall through + default : + result.append(input[i]); } - super.save(getProfileLocation(profileId)); } + return result.toString(); } /** @@ -122,12 +170,12 @@ public class ProfilePreferences extends EclipsePreferences { */ private IPath getDefaultLocation() { //use engine agent location for preferences if there is no self profile - AgentLocation location = (AgentLocation) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.SERVICE_NAME); + IAgentLocation location = (IAgentLocation) ServiceHelper.getService(EngineActivator.getContext(), IAgentLocation.SERVICE_NAME); if (location == null) { LogHelper.log(new Status(IStatus.WARNING, EngineActivator.ID, "Agent location service not available", new RuntimeException())); //$NON-NLS-1$ return null; } - IPath dataArea = new Path(URLUtil.toFile(location.getDataArea(EngineActivator.ID)).getAbsolutePath()); + IPath dataArea = new Path(URIUtil.toFile(location.getDataArea(EngineActivator.ID)).getAbsolutePath()); return computeLocation(dataArea, qualifier); } @@ -139,7 +187,7 @@ public class ProfilePreferences extends EclipsePreferences { // Walk backwards up the tree starting at this node. // This is important to avoid a chicken/egg thing on startup. IEclipsePreferences node = this; - for (int i = 3; i < segmentCount; i++) + for (int i = 4; i < segmentCount; i++) node = (EclipsePreferences) node.parent(); loadLevel = node; } @@ -149,8 +197,8 @@ public class ProfilePreferences extends EclipsePreferences { /** * Returns the location of the preference file for the given profile. */ - private IPath getProfileLocation(String profileId) { - SimpleProfileRegistry profileRegistry = (SimpleProfileRegistry) ServiceHelper.getService(EngineActivator.getContext(), IProfileRegistry.class.getName()); + private IPath getProfileLocation(IProvisioningAgent agent, String profileId) { + SimpleProfileRegistry profileRegistry = (SimpleProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); File profileDataDirectory = profileRegistry.getProfileDataDirectory(profileId); return computeLocation(new Path(profileDataDirectory.getAbsolutePath()), qualifier); } @@ -173,21 +221,27 @@ public class ProfilePreferences extends EclipsePreferences { */ protected void load() throws BackingStoreException { synchronized (((ProfilePreferences) parent).profileLock) { - String profileId = getSegment(absolutePath(), 1); - if (!containsProfile(profileId)) { - //use the default location for the self profile, otherwise just do nothing and return - if (IProfileRegistry.SELF.equals(profileId)) { - IPath location = getDefaultLocation(); - if (location != null) { - load(location); - return; + ServiceReference agentRef = getAgent(getSegment(absolutePath(), 1)); + IProvisioningAgent agent = (IProvisioningAgent) EngineActivator.getContext().getService(agentRef); + try { + String profileId = getSegment(absolutePath(), 2); + if (!containsProfile(agent, profileId)) { + //use the default location for the self profile, otherwise just do nothing and return + if (IProfileRegistry.SELF.equals(profileId)) { + IPath location = getDefaultLocation(); + if (location != null) { + load(location); + return; + } } + if (Tracing.DEBUG_PROFILE_PREFERENCES) + Tracing.debug("Not loading preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ + return; } - if (Tracing.DEBUG_PROFILE_PREFERENCES) - Tracing.debug("Not loading preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ - return; + load(getProfileLocation(agent, profileId)); + } finally { + EngineActivator.getContext().ungetService(agentRef); } - load(getProfileLocation(profileId)); } } |