blob: e559b8ebb5d3f57fa45fbbf6ca387ee9054cd363 [file] [log] [blame]
/*
* Copyright (c) 2014-2017 Eike Stepper (Loehne, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.oomph.p2.internal.core;
import org.eclipse.oomph.p2.P2Exception;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.internal.p2.engine.ISurrogateProfileHandler;
import org.eclipse.equinox.internal.p2.engine.Profile;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.index.IIndex;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import java.io.File;
import java.lang.ref.SoftReference;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @author Eike Stepper
*/
@SuppressWarnings("restriction")
public final class LazyProfile extends org.eclipse.equinox.internal.p2.engine.Profile
{
private final LazyProfileRegistry registry;
private final File profileDirectory;
private SoftReference<org.eclipse.equinox.internal.p2.engine.Profile> delegate;
private org.eclipse.equinox.internal.p2.engine.Profile parent;
/**
* The value for this is never actually used, but it ensures there is a strong reference so that the delegate is never garbage collection.
*/
@SuppressWarnings("unused")
private org.eclipse.equinox.internal.p2.engine.Profile self;
public LazyProfile(LazyProfileRegistry registry, String profileId, File profileDirectory)
{
super(registry.getProvisioningAgent(), profileId, null, null);
this.registry = registry;
this.profileDirectory = profileDirectory;
}
public synchronized org.eclipse.equinox.internal.p2.engine.Profile getDelegate(boolean loadOnDemand)
{
if (delegate != null)
{
org.eclipse.equinox.internal.p2.engine.Profile referent = delegate.get();
if (referent != null)
{
return referent;
}
delegate = null;
}
if (!loadOnDemand)
{
return null;
}
String profileId = getProfileId();
org.eclipse.equinox.internal.p2.engine.Profile referent = registry.loadProfile(profileId, profileDirectory);
if (referent == null)
{
throw new P2Exception("Profile '" + profileId + "' could not be loaded from " + profileDirectory);
}
referent.setParent(parent);
delegate = new SoftReference<org.eclipse.equinox.internal.p2.engine.Profile>(referent);
// Keep a strong reference to the referenced profile if this is the self profile.
if (getProfileId().equals(registry.self))
{
self = referent;
}
return referent;
}
private org.eclipse.equinox.internal.p2.engine.Profile getDelegate()
{
return getDelegate(true);
}
@Override
public IQueryResult<IInstallableUnit> query(IQuery<IInstallableUnit> query, IProgressMonitor monitor)
{
return getDelegate().query(query, monitor);
}
@Override
public IProfile getParentProfile()
{
return getDelegate().getParentProfile();
}
@Override
public synchronized void setParent(org.eclipse.equinox.internal.p2.engine.Profile parent)
{
this.parent = parent;
org.eclipse.equinox.internal.p2.engine.Profile delegate = getDelegate(false);
if (delegate != null)
{
delegate.setParent(parent);
}
}
@Override
public boolean isRootProfile()
{
return getDelegate().isRootProfile();
}
@Override
public void addSubProfile(String subProfileId) throws IllegalArgumentException
{
getDelegate().addSubProfile(subProfileId);
}
@Override
public void removeSubProfile(String subProfileId) throws IllegalArgumentException
{
getDelegate().removeSubProfile(subProfileId);
}
@Override
public boolean hasSubProfiles()
{
return getDelegate().hasSubProfiles();
}
@Override
public List<String> getSubProfileIds()
{
return getDelegate().getSubProfileIds();
}
@Override
public String getProperty(String key)
{
Profile delegate = getDelegate();
// If we're getting the cache property and this is for an installation with a shared bundle pool...
if (IProfile.PROP_CACHE.equals(key) && "true".equals(delegate.getProperty(org.eclipse.oomph.p2.core.Profile.PROP_PROFILE_SHARED_POOL)))
{
// If we're being called from org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry.updateRoamingProfile(Profile)
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace.length > 3 && "updateRoamingProfile".equals(stackTrace[2].getMethodName()))
{
// Return the value of the install folder instead.
// This will prevent that method from trying to change the value of the cache property.
return delegate.getProperty(IProfile.PROP_INSTALL_FOLDER);
}
}
return delegate.getProperty(key);
}
@Override
public String getLocalProperty(String key)
{
return getDelegate().getLocalProperty(key);
}
@Override
public void setProperty(String key, String value)
{
Profile delegate = getDelegate();
if (IProfile.PROP_CACHE.equals(key))
{
// If we're setting the cache property,
// and this is a profile for an Oomph installation with a shared bundle pool for which the cache property has already been set,
// we don't want org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry.updateRoamingProfile(Profile)
// to change the cache location to point to the installation.
if ("true".equals(delegate.getProperty(org.eclipse.oomph.p2.core.Profile.PROP_PROFILE_SHARED_POOL)) && delegate.getProperty(IProfile.PROP_CACHE) != null)
{
return;
}
}
delegate.setProperty(key, value);
}
@Override
public void removeProperty(String key)
{
getDelegate().removeProperty(key);
}
@Override
public synchronized IIndex<IInstallableUnit> getIndex(String memberName)
{
return getDelegate().getIndex(memberName);
}
@Override
public Iterator<IInstallableUnit> everything()
{
return getDelegate().everything();
}
@Override
public Object getManagedProperty(Object client, String memberName, Object key)
{
return getDelegate().getManagedProperty(client, memberName, key);
}
@Override
public IQueryResult<IInstallableUnit> available(IQuery<IInstallableUnit> query, IProgressMonitor monitor)
{
return getDelegate().available(query, monitor);
}
@Override
public String getInstallableUnitProperty(IInstallableUnit iu, String key)
{
return getDelegate().getInstallableUnitProperty(iu, key);
}
@Override
public String setInstallableUnitProperty(IInstallableUnit iu, String key, String value)
{
return getDelegate().setInstallableUnitProperty(iu, key, value);
}
@Override
public String removeInstallableUnitProperty(IInstallableUnit iu, String key)
{
return getDelegate().removeInstallableUnitProperty(iu, key);
}
@Override
public Map<String, String> getLocalProperties()
{
return getDelegate().getLocalProperties();
}
@Override
public Map<String, String> getProperties()
{
return getDelegate().getProperties();
}
@Override
public IProvisioningAgent getProvisioningAgent()
{
return getDelegate().getProvisioningAgent();
}
@Override
public void addProperties(Map<String, String> properties)
{
getDelegate().addProperties(properties);
}
@Override
public void addInstallableUnit(IInstallableUnit iu)
{
getDelegate().addInstallableUnit(iu);
}
@Override
public void removeInstallableUnit(IInstallableUnit iu)
{
getDelegate().removeInstallableUnit(iu);
}
@Override
public Map<String, String> getInstallableUnitProperties(IInstallableUnit iu)
{
return getDelegate().getInstallableUnitProperties(iu);
}
@Override
public void clearLocalProperties()
{
getDelegate().clearLocalProperties();
}
@Override
public boolean isChanged()
{
return getDelegate().isChanged();
}
@Override
public void setChanged(boolean isChanged)
{
getDelegate().setChanged(isChanged);
}
@Override
public void clearInstallableUnits()
{
getDelegate().clearInstallableUnits();
}
@Override
public org.eclipse.equinox.internal.p2.engine.Profile snapshot()
{
return getDelegate().snapshot();
}
@Override
public void addInstallableUnitProperties(IInstallableUnit iu, Map<String, String> properties)
{
getDelegate().addInstallableUnitProperties(iu, properties);
}
@Override
public void clearInstallableUnitProperties(IInstallableUnit iu)
{
getDelegate().clearInstallableUnitProperties(iu);
}
@Override
public void clearOrphanedInstallableUnitProperties()
{
getDelegate().clearOrphanedInstallableUnitProperties();
}
@Override
public long getTimestamp()
{
return getDelegate().getTimestamp();
}
@Override
public void setTimestamp(long millis)
{
getDelegate().setTimestamp(millis);
}
@Override
public void setSurrogateProfileHandler(ISurrogateProfileHandler surrogateProfileHandler)
{
getDelegate().setSurrogateProfileHandler(surrogateProfileHandler);
}
@Override
public String toString()
{
return getProfileId();
}
}