/*******************************************************************************
* 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);
}
}