/*****************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*****************************************************************************/
package org.eclipse.buckminster.core.metadata;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.UUID;
import java.util.regex.Pattern;
import org.eclipse.buckminster.core.CorePlugin;
import org.eclipse.buckminster.core.Messages;
import org.eclipse.buckminster.core.TargetPlatform;
import org.eclipse.buckminster.core.actor.IGlobalContext;
import org.eclipse.buckminster.core.cspec.IComponentIdentifier;
import org.eclipse.buckminster.core.cspec.IComponentRequest;
import org.eclipse.buckminster.core.cspec.model.CSpec;
import org.eclipse.buckminster.core.cspec.model.ComponentIdentifier;
import org.eclipse.buckminster.core.cspec.model.ComponentName;
import org.eclipse.buckminster.core.cspec.model.ComponentRequest;
import org.eclipse.buckminster.core.cspec.model.Generator;
import org.eclipse.buckminster.core.metadata.MetadataSynchronizer.WorkspaceCatchUpJob;
import org.eclipse.buckminster.core.metadata.model.BOMNode;
import org.eclipse.buckminster.core.metadata.model.BillOfMaterials;
import org.eclipse.buckminster.core.metadata.model.Materialization;
import org.eclipse.buckminster.core.metadata.model.Resolution;
import org.eclipse.buckminster.core.query.builder.AdvisorNodeBuilder;
import org.eclipse.buckminster.core.query.builder.ComponentQueryBuilder;
import org.eclipse.buckminster.core.reader.IReaderType;
import org.eclipse.buckminster.core.resolver.IResolver;
import org.eclipse.buckminster.core.resolver.LocalResolver;
import org.eclipse.buckminster.core.resolver.MainResolver;
import org.eclipse.buckminster.core.resolver.ResolutionContext;
import org.eclipse.buckminster.core.version.VersionHelper;
import org.eclipse.buckminster.runtime.MonitorUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
/**
* @author Thomas Hallgren
*/
public class WorkspaceInfo {
/**
* Qualified name of the project persistent property where the {@link UUID}
* of the component is stored.<br/>
* This property will be set on IResource elements that represent component
* roots such as projects or resources that is inner bindings in projects.
*/
public static final QualifiedName PPKEY_COMPONENT_ID = new QualifiedName(CorePlugin.CORE_NAMESPACE, "componentID"); //$NON-NLS-1$
/**
* Qualified name of the project persistent property where the a boolean
* value that indicates if the CSpec has been generated from other artifacts
* is stored.<br/>
* This property will be set on IResource elements that represent component
* roots such as projects or resources that is inner bindings in projects.
*/
public static final QualifiedName PPKEY_GENERATED_CSPEC = new QualifiedName(CorePlugin.CORE_NAMESPACE, "generatedCSpec"); //$NON-NLS-1$
private static final Pattern MATCH_ALL = Pattern.compile("^"); //$NON-NLS-1$
private static boolean hasBeenActivated;
private static boolean hasBeenFullyInitialized;
private static final HashMap<IComponentIdentifier, IPath> locationCache = new HashMap<IComponentIdentifier, IPath>();
private static final IResource[] noResources = new IResource[0];
private static final HashMap<IComponentIdentifier, Resolution> resolutionCache = new HashMap<IComponentIdentifier, Resolution>();
private static Stack<IGlobalContext> performContextStack;
private static final Map<ComponentIdentifier, Resolution> tpResolutions = new HashMap<ComponentIdentifier, Resolution>();
private static Resolution[] cachedActiveResolutions = new Resolution[0];
private static long cachedActiveResolutionsTimestamp = 0;
public static void clearCachedLocation(IComponentIdentifier cid) {
synchronized (locationCache) {
locationCache.remove(cid);
}
}
public static BillOfMaterials deepResolveLocal(IComponentRequest request, boolean useWorkspace, boolean continueOnError) throws CoreException {
checkFirstUse();
IResolver main = new MainResolver(getLocalResolutionContext(request, useWorkspace, continueOnError));
return main.resolve(new NullProgressMonitor());
}
public static void forceRefreshOnAll(IProgressMonitor monitor) {
CorePlugin plugin = CorePlugin.getDefault();
if (plugin == null)
// We're shutting down
return;
MultiStatus status = new MultiStatus(plugin.toString(), IStatus.OK, Messages.Problems_during_metadata_refresh, null);
monitor.beginTask(Messages.Refreshing_meta_data, 1000);
hasBeenActivated = true;
try {
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
wsRoot.accept(new MetadataSynchronizer.ResetVisitor());
MonitorUtils.worked(monitor, 50);
IProject[] projects = wsRoot.getProjects();
IResolution[] resolutions = StorageManager.getDefault().getResolutions().getElements();
MonitorUtils.worked(monitor, 50);
int ticksPerRefresh = 900 / (resolutions.length > 0 ? resolutions.length : (projects.length > 0 ? projects.length : 1));
// Re-resolve all known bundles from the target platform
//
for (IResolution res : resolutions) {
if (!IReaderType.ECLIPSE_PLATFORM.equals(res.getProvider().getReaderTypeId()))
continue;
try {
resolveLocal(res.getRequest(), false);
} catch (CoreException e) {
status.add(e.getStatus());
}
MonitorUtils.worked(monitor, ticksPerRefresh);
}
// Re-resolve all projects
//
for (IProject project : projects) {
try {
MetadataSynchronizer.refreshProject(project, MonitorUtils.subMonitor(monitor, ticksPerRefresh));
} catch (CoreException e) {
status.add(e.getStatus());
}
}
} catch (CoreException e) {
status.add(e.getStatus());
} finally {
monitor.done();
}
CorePlugin.logWarningsAndErrors(status);
}
public static List<Resolution> getAllResolutions() throws CoreException {
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
HashSet<Resolution> bld = new HashSet<Resolution>();
for (Resolution cr : getActiveResolutions(sm))
bld.add(cr);
for (Materialization mat : sm.getMaterializations().getElements()) {
try {
bld.add(mat.getResolution());
} catch (Exception e) {
// ignore
}
}
synchronized (tpResolutions) {
for (ComponentIdentifier ci : TargetPlatform.getInstance().getComponents()) {
Resolution tpRes = tpResolutions.get(ci);
if (tpRes == null) {
tpRes = getResolution(ci);
tpResolutions.put(ci, tpRes);
}
bld.add(tpRes);
}
}
ArrayList<Resolution> sorted = new ArrayList<Resolution>(bld);
Collections.sort(sorted, new Comparator<Resolution>() {
@Override
public int compare(Resolution o1, Resolution o2) {
int cmp = o1.getName().compareTo(o2.getName());
if (cmp == 0) {
Version v1 = o1.getVersion();
Version v2 = o2.getVersion();
if (v1 == null)
cmp = v2 == null ? 0 : -1;
else if (v2 == null)
cmp = 1;
else
cmp = v1.compareTo(v2);
}
return cmp;
}
});
return sorted;
}
public static ComponentIdentifier getComponentIdentifier(IResource resource) {
checkFirstUse();
String componentId = null;
try {
componentId = resource.getPersistentProperty(PPKEY_COMPONENT_ID);
return componentId == null ? null : ComponentIdentifier.parse(componentId);
} catch (CoreException e) {
return null;
}
}
/**
* Returns the full path of the materialization for the component denoted by
* the <code>componentIdentifier</code>
*
* @param componentIdentifier
* The identifier of the component
* @return The path of the location
* @throws MissingComponentException
* if the component cannot be found
* @throws AmbigousComponentException
* if more then one component is an equally good match
* @throws CoreException
* for other persistent storage related issues
*/
public static IPath getComponentLocation(ComponentIdentifier componentIdentifier) throws CoreException {
// Obtain the storage manager outside of the synchronization to avoid
// possible deadlock.
//
StorageManager.getDefault();
checkFirstUse();
synchronized (locationCache) {
IPath location = locationCache.get(componentIdentifier);
if (location != null)
return location;
Materialization mat = getMaterialization(componentIdentifier);
if (mat == null) {
Resolution resolution = getResolution(componentIdentifier);
location = resolution.getProvider().getReaderType().getFixedLocation(resolution);
if (location == null) {
if (performContextStack != null) {
mat = performContextStack.peek().getGeneratedMaterialization(componentIdentifier);
if (mat != null)
// We deliberately skip the cache here since
// generated
// material doesn't belong there.
return mat.getComponentLocation();
}
throw new MissingComponentException(componentIdentifier.toString());
}
} else
location = mat.getComponentLocation();
locationCache.put(componentIdentifier, location);
return location;
}
}
/**
* Returns the full path of the materialization for the component denoted by
* the <code>componentIdentifier</code>
*
* @param cspec
* The cspec of the component
* @return The path of the location
* @throws MissingComponentException
* if the component cannot be found
* @throws AmbigousComponentException
* if more then one component is an equally good match
* @throws CoreException
* for other persistent storage related issues
*/
public static IPath getComponentLocation(CSpec cspec) throws CoreException {
return getComponentLocation(cspec.getComponentIdentifier());
}
public static CSpec getCSpec(IResource resource) throws CoreException {
checkFirstUse();
ComponentIdentifier id = getComponentIdentifier(resource);
return id == null ? null : getResolution(id).getCSpec();
}
public static List<Generator> getGenerators(IComponentRequest request) throws CoreException {
List<Generator> generators = null;
for (Resolution res : getAllResolutions()) {
for (Generator generator : res.getCSpec().getGeneratorList()) {
if (request.designates(generator.getGeneratedIdentifier())) {
if (generators == null)
generators = new ArrayList<Generator>();
generators.add(generator);
}
}
}
if (generators == null)
generators = Collections.emptyList();
return generators;
}
public static Materialization getMaterialization(ComponentRequest request) throws CoreException {
// Add all components for which we have a materialization
//
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
Materialization bestFit = null;
for (Materialization mat : sm.getMaterializations().getElements()) {
ComponentIdentifier ci = mat.getComponentIdentifier();
if (!request.designates(ci))
continue;
if (!mat.getComponentLocation().toFile().exists()) {
mat.remove(StorageManager.getDefault());
mat = null;
continue;
}
if (bestFit == null || ci.compareTo(bestFit.getComponentIdentifier()) > 0)
bestFit = mat;
}
return bestFit;
}
public static Materialization getMaterialization(IComponentIdentifier cid) throws CoreException {
// Add all components for which we have a materialization
//
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
for (Materialization mat : sm.getMaterializations().getElements()) {
if (cid.equals(mat.getComponentIdentifier())) {
if (!mat.getComponentLocation().toFile().exists()) {
mat.remove(StorageManager.getDefault());
mat = null;
}
return mat;
}
}
return null;
}
/**
* Returns the optional <code>Materialization</code> for the component.
* Components found in the target platform will not have a materialization.
*
* @param resolution
* The resolution for which we want a Materialization
* @return The materialization or <code>null</code> if it could not be
* found.
* @throws CoreException
*/
public static Materialization getMaterialization(Resolution resolution) throws CoreException {
return getMaterialization(resolution.getComponentIdentifier());
}
/**
* Finds the open project that corresponds to the
* <code>componentIdentifier</code> and return it.
*
* @param componentIdentifier
* @return The found project or <code>null</code> if no open project was
* found.
* @throws CoreException
*/
public static IProject getProject(IComponentIdentifier componentIdentifier) throws CoreException {
return extractProject(getResources(componentIdentifier));
}
/**
* Finds the open project that corresponds to the
* <code>materialization</code> and return it.
*
* @param materialization
* @return The found project or <code>null</code> if no open project was
* found.
* @throws CoreException
*/
public static IProject getProject(Materialization materialization) throws CoreException {
return extractProject(getResources(materialization));
}
public static IProject[] getProjectsInResolution(IComponentIdentifier componentIdentifier) throws CoreException {
VersionRange versionRange = VersionHelper.exactRange(componentIdentifier.getVersion());
ComponentRequest componetRequest = new ComponentRequest(componentIdentifier.getName(), componentIdentifier.getComponentTypeID(), versionRange);
BillOfMaterials resolution = deepResolveLocal(componetRequest, true, true);
ArrayList<IProject> projects = new ArrayList<IProject>();
for (Resolution member : resolution.findAll(Collections.<Resolution> emptySet())) {
IProject project = getProject(member.getCSpec().getComponentIdentifier());
if (project != null)
projects.add(project);
}
return projects.toArray(new IProject[projects.size()]);
}
public static Resolution getResolution(ComponentIdentifier wanted) throws CoreException {
return getResolution(wanted, false);
}
public static Resolution getResolution(ComponentIdentifier wanted, boolean fromResolver) throws CoreException {
// Obtain the storage manager outside of the synchronization to avoid
// possible deadlock.
//
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
synchronized (resolutionCache) {
Resolution candidate = resolutionCache.get(wanted);
if (candidate == null) {
for (Resolution res : getActiveResolutions(sm)) {
ComponentIdentifier cid = res.getCSpec().getComponentIdentifier();
if (!wanted.matches(cid))
continue;
if (wanted.getVersion() != null) {
// This is an exact match
//
candidate = res;
break;
}
if (candidate == null) {
candidate = res;
continue;
}
// Both are without version. One must be without type then
//
ComponentIdentifier candCid = candidate.getCSpec().getComponentIdentifier();
if (candCid.getComponentType() == null) {
if (cid.getComponentType() == null)
throw new AmbigousComponentException(wanted.toString());
candidate = res;
} else {
if (cid.getComponentType() != null)
throw new AmbigousComponentException(wanted.toString());
}
}
}
if (candidate != null) {
resolutionCache.put(wanted, candidate);
return candidate;
}
}
if (!fromResolver) {
Version v = wanted.getVersion();
VersionRange vd = VersionHelper.exactRange(v);
try {
return resolveLocal(new ComponentRequest(wanted.getName(), wanted.getComponentTypeID(), vd), true);
} catch (CoreException e) {
CorePlugin.getLogger().debug(e, e.getMessage());
}
}
throw new MissingComponentException(wanted.toString());
}
/**
* Returns the <code>CSpec</code> that best corresponds to the given
* <code>request</code>.
*
* @param request
* The component request
* @return The found Resolution
* @throws MissingComponentException
* if the component cannot be found
* @throws AmbigousComponentException
* if more then one component is an equally good match
* @throws CoreException
* for other persistent storage related issues
*/
public static Resolution getResolution(ComponentRequest request, boolean fromResolver) throws CoreException {
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
Resolution candidate = null;
Resolution[] activeRess = getActiveResolutions(sm);
for (Resolution res : activeRess) {
ComponentIdentifier id = res.getCSpec().getComponentIdentifier();
if (request.designates(id) && (candidate == null || id.compareTo(candidate.getCSpec().getComponentIdentifier()) > 0))
candidate = res;
}
if (candidate == null) {
if (fromResolver)
return null;
try {
candidate = resolveLocal(request, true);
} catch (MissingComponentException e) {
throw e;
} catch (CoreException e) {
throw new MissingComponentException(request.toString());
}
}
return candidate;
}
/**
* Obtains the resources currently bound to the given
* <code>componentIdentifier</code> and returns them. An empty array is
* returned when no resource was found.
*
* @param componentIdentifier
* The component to search for
* @return The found workspace resources.
* @throws CoreException
*/
public static IResource[] getResources(IComponentIdentifier componentIdentifier) throws CoreException {
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
ISaxableStorage<Materialization> mats = sm.getMaterializations();
for (Materialization mat : mats.getElements()) {
if (componentIdentifier.equals(mat.getComponentIdentifier()))
return getResources(mat);
}
return noResources;
}
public static IResource[] getResources(IComponentRequest request) throws CoreException {
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
IResource[] allFound = noResources;
ISaxableStorage<Materialization> mats = sm.getMaterializations();
for (Materialization mat : mats.getElements()) {
if (!request.designates(mat.getComponentIdentifier()))
continue;
IResource[] resources = getResources(mat);
int top = resources.length;
if (top == 0)
continue;
if (allFound == noResources)
allFound = resources;
else {
IResource[] concat = new IResource[allFound.length + top];
System.arraycopy(allFound, 0, concat, 0, allFound.length);
System.arraycopy(resources, 0, concat, allFound.length, top);
allFound = concat;
}
}
return allFound;
}
public static IResource[] getResources(Materialization mat) throws CoreException {
checkFirstUse();
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
IPath location = mat.getComponentLocation();
URI locationURI = location.toFile().toURI();
return location.hasTrailingSeparator() ? wsRoot.findContainersForLocationURI(locationURI) : wsRoot.findFilesForLocationURI(locationURI);
}
/**
* Returns <code>true</code> if the workspace catch up job has been
* successfully run once and <code>false</code> otherwise.
*
* @return if the workspace catch up job has been run or not
* @see WorkspaceInfo#runWorkspaceCatchUpJob()
*/
public static boolean isFullyInitialized() {
return hasBeenFullyInitialized;
}
public static void popPerformContext() {
if (performContextStack == null)
throw new EmptyStackException();
performContextStack.pop();
if (performContextStack.isEmpty())
performContextStack = null;
}
public static void pushPerformContext(IGlobalContext context) {
if (performContextStack == null)
performContextStack = new Stack<IGlobalContext>();
performContextStack.push(context);
}
public static Resolution resolveLocal(IComponentRequest request, boolean useWorkspace) throws CoreException {
Resolution res;
if (performContextStack != null) {
res = performContextStack.peek().getGeneratedResolution(request);
if (res != null)
return res;
}
ResolutionContext ctx = getLocalResolutionContext(request, useWorkspace, false);
LocalResolver lr = new LocalResolver(ctx);
lr.setRecursiveResolve(false);
BOMNode node = lr.localResolve(ctx.getRootNodeQuery(), new NullProgressMonitor());
res = node == null ? null : node.getResolution();
if (res == null)
throw new MissingComponentException(request.toString());
return res;
}
public static void runWorkspaceCatchUpJob() {
if (!hasBeenFullyInitialized) {
WorkspaceCatchUpJob catchUpJob = new WorkspaceCatchUpJob();
catchUpJob.schedule();
try {
catchUpJob.join();
} catch (InterruptedException e) {
}
}
hasBeenFullyInitialized = true;
}
public static void setComponentIdentifier(IResource resource, IComponentIdentifier identifier) throws CoreException {
resource.setPersistentProperty(PPKEY_COMPONENT_ID, identifier == null ? null : identifier.toString());
}
public static void updateResolutionCache(IComponentIdentifier cid, Resolution resolution) {
synchronized (resolutionCache) {
if (resolution == null)
resolutionCache.remove(cid);
else
resolutionCache.put(cid, resolution);
}
}
public static void validateMaterializations() throws CoreException {
StorageManager sm = StorageManager.getDefault();
checkFirstUse();
for (Materialization mt : sm.getMaterializations().getElements())
if (!mt.getComponentLocation().toFile().exists())
mt.remove(sm);
}
private static void checkFirstUse() {
// We want the first caller to star the job. That job in turn will
// result in recursive calls that should return immediately.
//
synchronized (WorkspaceInfo.class) {
if (hasBeenActivated)
return;
hasBeenActivated = true;
}
runWorkspaceCatchUpJob();
}
private static IProject extractProject(IResource[] resources) {
int idx = resources.length;
while (--idx >= 0) {
IResource resource = resources[idx];
if (resource instanceof IProject) {
IProject project = (IProject) resource;
if (project.isOpen())
return project;
}
}
return null;
}
private static Resolution[] getActiveResolutions(StorageManager sm) throws CoreException {
synchronized (cachedActiveResolutions) {
long now = System.currentTimeMillis();
if (now - cachedActiveResolutionsTimestamp < 2000)
return cachedActiveResolutions;
// Add the newest version of each known resolution
//
HashMap<ComponentName, TimestampedKey> resolutionKeys = new HashMap<ComponentName, TimestampedKey>();
ArrayList<TimestampedKey> duplicates = null;
ISaxableStorage<Resolution> ress = sm.getResolutions();
ISaxableStorage<Materialization> mats = sm.getMaterializations();
synchronized (ress) {
for (Resolution res : ress.getElements()) {
UUID resId = res.getId();
ComponentIdentifier ci = res.getComponentIdentifier();
IPath location = getResolutionLocation(mats, res);
if (location == null)
continue;
ComponentName cn = ci.toPureComponentName();
TimestampedKey tsKey = new TimestampedKey(resId, ress.getCreationTime(resId));
TimestampedKey prevTsKey = resolutionKeys.put(cn, tsKey);
if (prevTsKey == null)
continue;
// Check real existence of locations. For performance
// reasons we
// only do
// this when ambiguities arise.
//
Resolution prevRes = ress.getElement(prevTsKey.getKey());
IPath prevLocation = getResolutionLocation(mats, prevRes);
if (prevLocation == null)
continue;
if (location.toFile().exists()) {
if (location.equals(prevLocation)) {
// Discriminate using timestamp
//
if (prevTsKey.getCreationTime() > tsKey.getCreationTime()) {
// We just replaced a newer entry. Put it back!
//
resolutionKeys.put(cn, prevTsKey);
}
continue;
}
if (!prevLocation.toFile().exists())
continue;
// A resolution towards the target platform will always
// have
// a lower
// precedence.
//
if (prevRes.getProvider().getReaderTypeId().equals(IReaderType.ECLIPSE_PLATFORM)) {
if (!res.getProvider().getReaderTypeId().equals(IReaderType.ECLIPSE_PLATFORM))
continue;
} else {
if (res.getProvider().getReaderTypeId().equals(IReaderType.ECLIPSE_PLATFORM)) {
resolutionKeys.put(cn, prevTsKey);
continue;
}
}
Version currVersion = ci.getVersion();
Version prevVersion = prevRes.getComponentIdentifier().getVersion();
if (VersionHelper.equalsUnqualified(currVersion, prevVersion)) {
// Discriminate using timestamp
//
if (prevTsKey.getCreationTime() > tsKey.getCreationTime())
resolutionKeys.put(cn, prevTsKey);
continue;
}
// Apparently we have both locations present so we
// cannot
// discriminate one of them
//
if (duplicates == null)
duplicates = new ArrayList<TimestampedKey>();
duplicates.add(prevTsKey);
CorePlugin
.getLogger()
.debug("Found two entries for component %s. Version %s located at %s and version %s at %s", cn, currVersion, location, prevVersion, prevLocation); //$NON-NLS-1$
continue;
}
if (prevLocation.toFile().exists()) {
// New entry is bogus and old entry is valid
//
resolutionKeys.put(cn, prevTsKey);
} else {
// None of the entries were valid. Simply remove the
// entry
//
resolutionKeys.remove(cn);
}
}
}
int top = resolutionKeys.size();
if (duplicates != null)
top += duplicates.size();
Resolution[] result = new Resolution[top];
int idx = 0;
for (TimestampedKey tsKey : resolutionKeys.values())
result[idx++] = ress.getElement(tsKey.getKey());
if (duplicates != null)
for (TimestampedKey tsKey : duplicates)
result[idx++] = ress.getElement(tsKey.getKey());
cachedActiveResolutions = result;
cachedActiveResolutionsTimestamp = System.currentTimeMillis();
return result;
}
}
private static ResolutionContext getLocalResolutionContext(IComponentRequest request, boolean useWorkspace, boolean continueOnError) {
ComponentQueryBuilder qbld = new ComponentQueryBuilder();
qbld.setRootRequest(request);
qbld.setPlatformAgnostic(true);
// Add an advisor node that matches the request and prohibits that we
// do something using an existing materialization or something external.
//
AdvisorNodeBuilder nodeBld = qbld.addAdvisorNode();
nodeBld.setNamePattern(Pattern.compile('^' + Pattern.quote(request.getName()) + '$'));
nodeBld.setComponentTypeID(request.getComponentTypeID());
nodeBld.setUseTargetPlatform(true);
nodeBld.setUseWorkspace(useWorkspace);
nodeBld.setUseMaterialization(false);
nodeBld.setUseRemoteResolution(false);
// Add an advisor node that matches all remaining components and
// prohibits that we do something external.
//
nodeBld = qbld.addAdvisorNode();
nodeBld.setNamePattern(MATCH_ALL);
nodeBld.setUseTargetPlatform(true);
nodeBld.setUseWorkspace(useWorkspace);
nodeBld.setUseMaterialization(useWorkspace);
nodeBld.setUseRemoteResolution(false);
nodeBld.setUseRemoteResolution(false);
ResolutionContext ctx = new ResolutionContext(qbld.createComponentQuery());
ctx.setSilentStatus(true);
ctx.setContinueOnError(continueOnError);
return ctx;
}
private static IPath getResolutionLocation(ISaxableStorage<Materialization> mats, Resolution res) throws CoreException {
// Obtain the storage manager outside of the synchronization to avoid
// possible deadlock.
//
StorageManager.getDefault();
checkFirstUse();
IPath location;
ComponentIdentifier ci = res.getComponentIdentifier();
synchronized (locationCache) {
location = locationCache.get(ci);
if (location == null) {
for (Materialization mat : mats.getElements()) {
if (mat.getComponentIdentifier().equals(ci)) {
location = mat.getComponentLocation();
break;
}
}
if (location == null)
location = res.getProvider().getReaderType().getFixedLocation(res);
if (location != null)
locationCache.put(ci, location);
}
}
return location;
}
}