|
Lines 11-25
Link Here
|
| 11 |
package org.eclipse.equinox.internal.p2.engine; |
11 |
package org.eclipse.equinox.internal.p2.engine; |
| 12 |
|
12 |
|
| 13 |
import java.io.File; |
13 |
import java.io.File; |
| 14 |
import java.util.*; |
14 |
import java.util.HashSet; |
|
|
15 |
import java.util.Set; |
| 15 |
import org.eclipse.core.internal.preferences.EclipsePreferences; |
16 |
import org.eclipse.core.internal.preferences.EclipsePreferences; |
| 16 |
import org.eclipse.core.runtime.*; |
17 |
import org.eclipse.core.runtime.*; |
| 17 |
import org.eclipse.core.runtime.jobs.Job; |
18 |
import org.eclipse.core.runtime.jobs.Job; |
| 18 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
19 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| 19 |
import org.eclipse.equinox.internal.p2.core.helpers.*; |
20 |
import org.eclipse.equinox.internal.p2.core.helpers.*; |
| 20 |
import org.eclipse.equinox.internal.provisional.p2.core.location.AgentLocation; |
21 |
import org.eclipse.equinox.internal.provisional.p2.core.location.AgentLocation; |
| 21 |
import org.eclipse.equinox.internal.provisional.p2.engine.*; |
22 |
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile; |
| 22 |
import org.eclipse.osgi.util.NLS; |
23 |
import org.eclipse.equinox.internal.provisional.p2.engine.IProfileRegistry; |
| 23 |
import org.osgi.framework.Bundle; |
24 |
import org.osgi.framework.Bundle; |
| 24 |
import org.osgi.framework.BundleContext; |
25 |
import org.osgi.framework.BundleContext; |
| 25 |
import org.osgi.service.prefs.BackingStoreException; |
26 |
import org.osgi.service.prefs.BackingStoreException; |
|
Lines 30-44
Link Here
|
| 30 |
* that is used when there is no currently running profile. |
31 |
* that is used when there is no currently running profile. |
| 31 |
*/ |
32 |
*/ |
| 32 |
public class ProfilePreferences extends EclipsePreferences { |
33 |
public class ProfilePreferences extends EclipsePreferences { |
| 33 |
private static final long SAVE_SCHEDULE_DELAY = 500; |
|
|
| 34 |
public static final Object PROFILE_SAVE_JOB_FAMILY = new Object(); |
| 35 |
|
| 36 |
private class SaveJob extends Job { |
34 |
private class SaveJob extends Job { |
| 37 |
SaveJob() { |
35 |
SaveJob() { |
| 38 |
super(Messages.ProfilePreferences_saving); |
36 |
super(Messages.ProfilePreferences_saving); |
| 39 |
setSystem(true); |
37 |
setSystem(true); |
| 40 |
} |
38 |
} |
| 41 |
|
39 |
|
|
|
40 |
public boolean belongsTo(Object family) { |
| 41 |
return family == PROFILE_SAVE_JOB_FAMILY; |
| 42 |
} |
| 43 |
|
| 42 |
protected IStatus run(IProgressMonitor monitor) { |
44 |
protected IStatus run(IProgressMonitor monitor) { |
| 43 |
try { |
45 |
try { |
| 44 |
doSave(); |
46 |
doSave(); |
|
Lines 47-67
Link Here
|
| 47 |
} |
49 |
} |
| 48 |
return Status.OK_STATUS; |
50 |
return Status.OK_STATUS; |
| 49 |
} |
51 |
} |
| 50 |
|
|
|
| 51 |
public boolean belongsTo(Object family) { |
| 52 |
return family == PROFILE_SAVE_JOB_FAMILY; |
| 53 |
} |
| 54 |
} |
52 |
} |
| 55 |
|
53 |
|
| 56 |
private int segmentCount; |
|
|
| 57 |
private String qualifier; |
| 58 |
//private IPath location; |
| 59 |
private IEclipsePreferences loadLevel; |
| 60 |
// cache which nodes have been loaded from disk |
54 |
// cache which nodes have been loaded from disk |
| 61 |
private static Set loadedNodes = new HashSet(); |
55 |
private static Set loadedNodes = new HashSet(); |
| 62 |
|
56 |
|
|
|
57 |
public static final Object PROFILE_SAVE_JOB_FAMILY = new Object(); |
| 58 |
|
| 59 |
private static final long SAVE_SCHEDULE_DELAY = 500; |
| 60 |
//private IPath location; |
| 61 |
private IEclipsePreferences loadLevel; |
| 63 |
private Object profileLock; |
62 |
private Object profileLock; |
|
|
63 |
private String qualifier; |
| 64 |
|
| 64 |
private SaveJob saveJob; |
65 |
private SaveJob saveJob; |
|
|
66 |
private int segmentCount; |
| 65 |
|
67 |
|
| 66 |
public ProfilePreferences() { |
68 |
public ProfilePreferences() { |
| 67 |
this(null, null); |
69 |
this(null, null); |
|
Lines 94-102
Link Here
|
| 94 |
return result; |
96 |
return result; |
| 95 |
} |
97 |
} |
| 96 |
|
98 |
|
| 97 |
public void removeNode() throws BackingStoreException { |
99 |
/* |
| 98 |
super.removeNode(); |
100 |
* (non-Javadoc) |
| 99 |
loadedNodes.remove(this.absolutePath()); |
101 |
* Create an Engine phase to save profile preferences |
|
|
102 |
*/ |
| 103 |
protected void doSave() throws BackingStoreException { |
| 104 |
synchronized (((ProfilePreferences) parent).profileLock) { |
| 105 |
String profileId = getSegment(absolutePath(), 1); |
| 106 |
IProfile profile = computeProfile(profileId); |
| 107 |
if (profile == null) { |
| 108 |
//use the default location for the self profile, otherwise just do nothing and return |
| 109 |
if (IProfileRegistry.SELF.equals(profileId)) { |
| 110 |
IPath location = getDefaultLocation(); |
| 111 |
if (location != null) { |
| 112 |
super.save(location); |
| 113 |
return; |
| 114 |
} |
| 115 |
} |
| 116 |
if (Tracing.DEBUG_PROFILE_PREFERENCES) |
| 117 |
Tracing.debug("Not saving preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ |
| 118 |
return; |
| 119 |
} |
| 120 |
super.save(getProfileLocation(profile)); |
| 121 |
} |
| 122 |
} |
| 123 |
|
| 124 |
/** |
| 125 |
* Returns the preference file to use when there is no active profile. |
| 126 |
*/ |
| 127 |
private IPath getDefaultLocation() { |
| 128 |
//use engine agent location for preferences if there is no self profile |
| 129 |
AgentLocation location = (AgentLocation) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.SERVICE_NAME); |
| 130 |
if (location == null) { |
| 131 |
LogHelper.log(new Status(IStatus.WARNING, EngineActivator.ID, "Agent location service not available", new RuntimeException())); //$NON-NLS-1$ |
| 132 |
return null; |
| 133 |
} |
| 134 |
IPath dataArea = new Path(URLUtil.toFile(location.getDataArea(EngineActivator.ID)).getAbsolutePath()); |
| 135 |
return computeLocation(dataArea, qualifier); |
| 100 |
} |
136 |
} |
| 101 |
|
137 |
|
| 102 |
protected IEclipsePreferences getLoadLevel() { |
138 |
protected IEclipsePreferences getLoadLevel() { |
|
Lines 114-133
Link Here
|
| 114 |
return loadLevel; |
150 |
return loadLevel; |
| 115 |
} |
151 |
} |
| 116 |
|
152 |
|
| 117 |
protected synchronized boolean isAlreadyLoaded(IEclipsePreferences node) { |
153 |
/** |
| 118 |
return loadedNodes.contains(node.absolutePath()); |
154 |
* Returns the location of the preference file for the given profile. |
|
|
155 |
*/ |
| 156 |
private IPath getProfileLocation(IProfile profile) { |
| 157 |
SimpleProfileRegistry profileRegistry = (SimpleProfileRegistry) ServiceHelper.getService(EngineActivator.getContext(), IProfileRegistry.class.getName()); |
| 158 |
File profileDataDirectory = profileRegistry.getProfileDataDirectory((Profile) profile); |
| 159 |
return computeLocation(new Path(profileDataDirectory.getAbsolutePath()), qualifier); |
| 119 |
} |
160 |
} |
| 120 |
|
161 |
|
| 121 |
protected synchronized boolean isAlreadyLoaded(String path) { |
162 |
protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String nodeName, Object context) { |
| 122 |
return loadedNodes.contains(path); |
163 |
return new ProfilePreferences(nodeParent, nodeName); |
| 123 |
} |
164 |
} |
| 124 |
|
165 |
|
| 125 |
protected synchronized void loaded() { |
166 |
protected synchronized boolean isAlreadyLoaded(IEclipsePreferences node) { |
| 126 |
loadedNodes.add(name()); |
167 |
return loadedNodes.contains(node.absolutePath()); |
| 127 |
} |
168 |
} |
| 128 |
|
169 |
|
| 129 |
protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String nodeName, Object context) { |
170 |
protected synchronized boolean isAlreadyLoaded(String path) { |
| 130 |
return new ProfilePreferences(nodeParent, nodeName); |
171 |
return loadedNodes.contains(path); |
| 131 |
} |
172 |
} |
| 132 |
|
173 |
|
| 133 |
/* |
174 |
/* |
|
Lines 141-147
Link Here
|
| 141 |
if (profile == null) { |
182 |
if (profile == null) { |
| 142 |
//use the default location for the self profile, otherwise just do nothing and return |
183 |
//use the default location for the self profile, otherwise just do nothing and return |
| 143 |
if (IProfileRegistry.SELF.equals(profileId)) { |
184 |
if (IProfileRegistry.SELF.equals(profileId)) { |
| 144 |
File location = getDefaultLocation(); |
185 |
IPath location = getDefaultLocation(); |
| 145 |
if (location != null) { |
186 |
if (location != null) { |
| 146 |
load(location); |
187 |
load(location); |
| 147 |
return; |
188 |
return; |
|
Lines 151-185
Link Here
|
| 151 |
Tracing.debug("Not loading preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ |
192 |
Tracing.debug("Not loading preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ |
| 152 |
return; |
193 |
return; |
| 153 |
} |
194 |
} |
| 154 |
IEngine engine = (IEngine) ServiceHelper.getService(EngineActivator.getContext(), IEngine.SERVICE_NAME); |
195 |
load(getProfileLocation(profile)); |
| 155 |
if (engine == null) { |
|
|
| 156 |
throw new BackingStoreException(NLS.bind(Messages.ProfilePreferences_load_failed, profile.getProfileId())); |
| 157 |
} |
| 158 |
PhaseSet set = new ProfilePreferencePhaseSet(new PreferenceLoad()); |
| 159 |
Exception failure; |
| 160 |
try { |
| 161 |
IStatus status = engine.perform(profile, set, new Operand[0], null, null); |
| 162 |
// Check return status. |
| 163 |
if (status.isOK()) |
| 164 |
return; |
| 165 |
failure = (Exception) status.getException(); |
| 166 |
} catch (IllegalStateException e) { |
| 167 |
failure = e; |
| 168 |
} |
| 169 |
if (failure != null && failure instanceof BackingStoreException) |
| 170 |
throw (BackingStoreException) failure; |
| 171 |
throw new BackingStoreException(NLS.bind(Messages.ProfilePreferences_load_failed, profile.getProfileId()), failure); |
| 172 |
} |
196 |
} |
| 173 |
} |
197 |
} |
| 174 |
|
198 |
|
| 175 |
private File getDefaultLocation() { |
199 |
protected synchronized void loaded() { |
| 176 |
//use engine agent location for preferences if there is no self profile |
200 |
loadedNodes.add(name()); |
| 177 |
AgentLocation location = (AgentLocation) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.SERVICE_NAME); |
201 |
} |
| 178 |
if (location == null) { |
202 |
|
| 179 |
LogHelper.log(new Status(IStatus.WARNING, EngineActivator.ID, "Agent location service not available", new RuntimeException())); //$NON-NLS-1$ |
203 |
public void removeNode() throws BackingStoreException { |
| 180 |
return null; |
204 |
super.removeNode(); |
| 181 |
} |
205 |
loadedNodes.remove(this.absolutePath()); |
| 182 |
return URLUtil.toFile(location.getDataArea(EngineActivator.ID)); |
|
|
| 183 |
} |
206 |
} |
| 184 |
|
207 |
|
| 185 |
/** |
208 |
/** |
|
Lines 200-309
Link Here
|
| 200 |
//bundle has been stopped concurrently, so don't save |
223 |
//bundle has been stopped concurrently, so don't save |
| 201 |
} |
224 |
} |
| 202 |
} |
225 |
} |
| 203 |
|
|
|
| 204 |
/* |
| 205 |
* (non-Javadoc) |
| 206 |
* Create an Engine phase to save profile preferences |
| 207 |
*/ |
| 208 |
protected void doSave() throws BackingStoreException { |
| 209 |
synchronized (((ProfilePreferences) parent).profileLock) { |
| 210 |
String profileId = getSegment(absolutePath(), 1); |
| 211 |
IProfile profile = computeProfile(profileId); |
| 212 |
if (profile == null) { |
| 213 |
//use the default location for the self profile, otherwise just do nothing and return |
| 214 |
if (IProfileRegistry.SELF.equals(profileId)) { |
| 215 |
File location = getDefaultLocation(); |
| 216 |
if (location != null) { |
| 217 |
save(location); |
| 218 |
return; |
| 219 |
} |
| 220 |
} |
| 221 |
if (Tracing.DEBUG_PROFILE_PREFERENCES) |
| 222 |
Tracing.debug("Not saving preferences since there is no file for node: " + absolutePath()); //$NON-NLS-1$ |
| 223 |
return; |
| 224 |
} |
| 225 |
IEngine engine = (IEngine) ServiceHelper.getService(EngineActivator.getContext(), IEngine.SERVICE_NAME); |
| 226 |
if (engine == null) { |
| 227 |
throw new BackingStoreException(NLS.bind(Messages.ProfilePreferences_save_failed, profile.getProfileId())); |
| 228 |
} |
| 229 |
PhaseSet set = new ProfilePreferencePhaseSet(new PreferenceFlush()); |
| 230 |
Exception failure; |
| 231 |
try { |
| 232 |
IStatus status = engine.perform(profile, set, new Operand[0], null, null); |
| 233 |
// Check return status. |
| 234 |
if (status.isOK()) |
| 235 |
return; |
| 236 |
failure = (Exception) status.getException(); |
| 237 |
} catch (IllegalStateException e) { |
| 238 |
failure = e; |
| 239 |
} |
| 240 |
if (failure != null && failure instanceof BackingStoreException) |
| 241 |
throw (BackingStoreException) failure; |
| 242 |
throw new BackingStoreException(NLS.bind(Messages.ProfilePreferences_save_failed, profile.getProfileId()), failure); |
| 243 |
} |
| 244 |
} |
| 245 |
|
| 246 |
public void load(File directory) throws BackingStoreException { |
| 247 |
super.load(computeLocation(new Path(directory.getAbsolutePath()), qualifier)); |
| 248 |
} |
| 249 |
|
| 250 |
public void save(File directory) throws BackingStoreException { |
| 251 |
super.save(computeLocation(new Path(directory.getAbsolutePath()), qualifier)); |
| 252 |
} |
| 253 |
|
| 254 |
// Simple PhaseSet used when loading or saving profile preferences |
| 255 |
private class ProfilePreferencePhaseSet extends PhaseSet { |
| 256 |
|
| 257 |
public ProfilePreferencePhaseSet(Phase phase) { |
| 258 |
super(new Phase[] {phase}); |
| 259 |
} |
| 260 |
} |
| 261 |
|
| 262 |
private class PreferenceFlush extends Phase { |
| 263 |
private static final String PHASE_ID = "preferenceFlush"; //$NON-NLS-1$ |
| 264 |
|
| 265 |
public PreferenceFlush() { |
| 266 |
super(PHASE_ID, 1); |
| 267 |
} |
| 268 |
|
| 269 |
protected ProvisioningAction[] getActions(Operand operand) { |
| 270 |
return null; |
| 271 |
} |
| 272 |
|
| 273 |
protected IStatus completePhase(IProgressMonitor monitor, IProfile phaseProfile, Map parameters) { |
| 274 |
File dataDirectory = (File) parameters.get(PARM_PROFILE_DATA_DIRECTORY); |
| 275 |
if (dataDirectory == null) |
| 276 |
return new Status(IStatus.ERROR, EngineActivator.ID, Messages.ProfilePreferences_nullDir); |
| 277 |
try { |
| 278 |
save(dataDirectory); |
| 279 |
} catch (BackingStoreException e) { |
| 280 |
return new Status(IStatus.ERROR, EngineActivator.ID, e.getMessage(), e); |
| 281 |
} |
| 282 |
return Status.OK_STATUS; |
| 283 |
} |
| 284 |
} |
| 285 |
|
| 286 |
private class PreferenceLoad extends Phase { |
| 287 |
private static final String PHASE_ID = "preferenceLoad"; //$NON-NLS-1$ |
| 288 |
|
| 289 |
public PreferenceLoad() { |
| 290 |
super(PHASE_ID, 1); |
| 291 |
} |
| 292 |
|
| 293 |
protected ProvisioningAction[] getActions(Operand operand) { |
| 294 |
return null; |
| 295 |
} |
| 296 |
|
| 297 |
protected IStatus completePhase(IProgressMonitor monitor, IProfile phaseProfile, Map parameters) { |
| 298 |
File dataDirectory = (File) parameters.get(PARM_PROFILE_DATA_DIRECTORY); |
| 299 |
if (dataDirectory == null) |
| 300 |
return new Status(IStatus.ERROR, EngineActivator.ID, Messages.ProfilePreferences_nullDir); |
| 301 |
try { |
| 302 |
load(dataDirectory); |
| 303 |
} catch (BackingStoreException e) { |
| 304 |
return new Status(IStatus.ERROR, EngineActivator.ID, e.getMessage(), e); |
| 305 |
} |
| 306 |
return Status.OK_STATUS; |
| 307 |
} |
| 308 |
} |
| 309 |
} |
226 |
} |