/******************************************************************************* * Copyright (c) 2004, 2011 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 - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.make.internal.core.scannerconfig2; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2Set; import org.eclipse.cdt.make.core.scannerconfig.InfoContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Preferences; /** * Manages profiles per project * * @author vhirsl */ public final class ScannerConfigProfileManager { public static final String SI_PROFILE_SIMPLE_ID = "ScannerConfigurationDiscoveryProfile"; //$NON-NLS-1$ public static final String PER_PROJECT_PROFILE_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCStandardMakePerProjectProfile"; //$NON-NLS-1$ public static final String NULL_PROFILE_ID = "";//$NON-NLS-1$ public static final String DEFAULT_SI_PROFILE_ID = NULL_PROFILE_ID; private final Map<IProject, Map<InfoContext, Object>> projectToProfileInstanceMap; private List<String> profileIds; private List<String> contextAwareProfileIds; private final Object fLock = new Object(); /** * Singleton pattern */ private ScannerConfigProfileManager() { projectToProfileInstanceMap = new HashMap<IProject, Map<InfoContext, Object>>(); } private static final ScannerConfigProfileManager instance = new ScannerConfigProfileManager(); public static ScannerConfigProfileManager getInstance() { return instance; } private String getProfileId(IProject project, InfoContext context) { String profileId; try { IScannerConfigBuilderInfo2Set container = createScannerConfigBuildInfo2Set(project); IScannerConfigBuilderInfo2 buildInfo = container.getInfo(context); if(buildInfo == null) buildInfo = container.getInfo(new InfoContext(project)); profileId = buildInfo.getSelectedProfileId(); } catch (CoreException e) { MakeCorePlugin.log(e); profileId = DEFAULT_SI_PROFILE_ID; } return profileId; } /** * For projects that do not have profile id specified in .project file. * For example managed projects. */ public void addProfile(IProject project, ScannerConfigProfile profile) { addProfile(project, new InfoContext(project), profile); } public void addProfile(IProject project, InfoContext context, ScannerConfigProfile profile) { getProfileMap(project, true).put(context, profile); } private Map<InfoContext, Object> getProfileMap(IProject project, boolean create){ synchronized (fLock) { Map<InfoContext, Object> map = projectToProfileInstanceMap.get(project); if(map == null && create){ map = new HashMap<InfoContext, Object>(); projectToProfileInstanceMap.put(project, map); } return Collections.synchronizedMap(map); } } public void handleProjectRemoved(IProject project){ synchronized (fLock) { projectToProfileInstanceMap.remove(project); } } /** * @param profileId - if null, get the one associated with the project * @return the scannerConfigProfile instance for a project. */ public SCProfileInstance getSCProfileInstance(IProject project, String profileId) { return getSCProfileInstance(project, new InfoContext(project), profileId); } public SCProfileInstance getSCProfileInstance(IProject project, InfoContext context, String profileId) { // if not specified read from .project file if (profileId == NULL_PROFILE_ID) { profileId = getProfileId(project, context); } synchronized (fLock) { // is the project's profile already loaded? Map<InfoContext, Object> map = getProfileMap(project, true); SoftReference<SCProfileInstance> profileInstanceReference = (SoftReference<SCProfileInstance>) map.get(context); SCProfileInstance profileInstance = profileInstanceReference != null ? profileInstanceReference.get() : null; if (profileInstance == null || !profileInstance.getProfile().getId().equals(profileId)) { profileInstance = new SCProfileInstance(project, context, getSCProfileConfiguration(profileId)); map.put(context, new SoftReference<SCProfileInstance>(profileInstance)); } return profileInstance; } } public SCProfileInstance getSCProfileInstance(String profileId) { SCProfileInstance profileInstance = null; if (profileId != NULL_PROFILE_ID) { profileInstance = new SCProfileInstance(null, getSCProfileConfiguration(profileId)); } return profileInstance; } /** * @param profileId - if null, get the default one * @return Returns the scannerConfigProfile for a project. */ public ScannerConfigProfile getSCProfileConfiguration(String profileId) { profileId = (profileId == NULL_PROFILE_ID) ? getDefaultSIProfileId() : profileId; return new ScannerConfigProfile(profileId); } /** * @return a list of available scanner config profile id's. */ public List<String> getProfileIds() { synchronized (fLock) { if (profileIds == null) { profileIds = new ArrayList<String>(); IExtensionPoint extension = Platform.getExtensionRegistry(). getExtensionPoint(MakeCorePlugin.PLUGIN_ID, ScannerConfigProfileManager.SI_PROFILE_SIMPLE_ID); if (extension != null) { IExtension[] extensions = extension.getExtensions(); for (int i = 0; i < extensions.length; ++i) { String rProfileId = extensions[i].getUniqueIdentifier(); profileIds.add(rProfileId); } } } } return Collections.unmodifiableList(profileIds); } /** * @return the list of profile IDs supported for this context */ public List<String> getProfileIds(InfoContext context){ if(context.isDefaultContext() || context.getProject() == null) return getProfileIds(); synchronized (fLock) { if(contextAwareProfileIds == null){ contextAwareProfileIds = new ArrayList<String>(); List<String> all = getProfileIds(); for(int i = 0; i < all.size(); i++){ String id = all.get(i); ScannerConfigProfile profile = getSCProfileConfiguration(id); if(profile.supportsContext()) contextAwareProfileIds.add(id); } } } return Collections.unmodifiableList(contextAwareProfileIds); } /** * @return default profile id */ public static String getDefaultSIProfileId() { return DEFAULT_SI_PROFILE_ID; } /** * Set selectedProfile to profileId */ public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(IProject project, String profileId) throws CoreException { return ScannerConfigInfoFactory2.create(project, profileId); } /** * Use stored selectedProfile */ public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(IProject project) throws CoreException { return ScannerConfigInfoFactory2.create(project, ScannerConfigProfileManager.NULL_PROFILE_ID); } public static IScannerConfigBuilderInfo2Set createScannerConfigBuildInfo2Set(IProject project) throws CoreException { return ScannerConfigInfoFactory2.createInfoSet(project, ScannerConfigProfileManager.NULL_PROFILE_ID); } public static IScannerConfigBuilderInfo2Set createScannerConfigBuildInfo2Set(IProject project, String profileId) throws CoreException { return ScannerConfigInfoFactory2.createInfoSet(project, profileId); } public static IScannerConfigBuilderInfo2Set createScannerConfigBuildInfo2Set(Preferences prefs, boolean useDefaults) throws CoreException { return ScannerConfigInfoFactory2.createInfoSet(prefs, ScannerConfigProfileManager.NULL_PROFILE_ID, useDefaults); } public static IScannerConfigBuilderInfo2Set createScannerConfigBuildInfo2Set(Preferences prefs, String profileId, boolean useDefaults) throws CoreException { return ScannerConfigInfoFactory2.createInfoSet(prefs, profileId, useDefaults); } /** * Set selectedProfile to profileId */ public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(Preferences prefs, String profileId, boolean useDefaults) { return ScannerConfigInfoFactory2.create(prefs, profileId, useDefaults); } /** * Use stored selectedProfile */ public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(Preferences prefs, boolean useDefaults) { return ScannerConfigInfoFactory2.create(prefs, ScannerConfigProfileManager.NULL_PROFILE_ID, useDefaults); } }