/* * Copyright (c) 2013, 2015 QNX Software Systems 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 */ package org.eclipse.cdt.internal.qt.core.index; import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.internal.qt.core.index.IQMakeEnvProvider.IController; import org.eclipse.core.expressions.EvaluationContext; import org.eclipse.core.expressions.EvaluationResult; import org.eclipse.core.expressions.Expression; import org.eclipse.core.expressions.ExpressionConverter; import org.eclipse.core.expressions.ExpressionTagNames; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; /** * Represents a IQMakeEnvProvider that is registered via qmakeEnvProvider extension point. */ public final class QMakeEnvProviderDescriptor implements Comparable<QMakeEnvProviderDescriptor> { private static final String ATTR_CLASS = "class"; //$NON-NLS-1$ private static final String ATTR_PRIORITY = "priority"; //$NON-NLS-1$ private static final String VAR_PROJECTNATURES = "projectNatures"; //$NON-NLS-1$ private final IConfigurationElement element; private final String id; private final int priority; private final AtomicReference<Boolean> evaluation = new AtomicReference<Boolean>(); private final Expression enablementExpression; QMakeEnvProviderDescriptor(IConfigurationElement element) { this.element = element; id = element.getContributor().getName(); // parse priority int prio = 0; String priorityString = element.getAttribute(ATTR_PRIORITY); if (priorityString != null) { try { prio = Integer.parseInt(priorityString); } catch (NumberFormatException e) { Activator.log("Invalid priority value of " + id, e); //$NON-NLS-1$ } } this.priority = prio; // parse enablement expression Expression expr = null; IConfigurationElement[] children = element.getChildren(ExpressionTagNames.ENABLEMENT); switch (children.length) { case 0: evaluation.set(Boolean.TRUE); break; case 1: try { ExpressionConverter parser = ExpressionConverter.getDefault(); expr = parser.perform(children[0]); } catch (CoreException e) { Activator.log("Error in enablement expression of " + id, e); //$NON-NLS-1$ } break; default: Activator.log("Too many enablement expressions for " + id); //$NON-NLS-1$ evaluation.set(Boolean.FALSE); break; } enablementExpression = expr; } @Override public int compareTo(QMakeEnvProviderDescriptor that) { if (that == null) { return -1; } return this.priority - that.priority; } /** * Used by QMakeEnvProviderManager to ask for creating a IQMakeEnv for a specific IQMakeEnvProvider.IController using the related IQMakeEnvProvider * * @param controller the controller * @return the IQMakeEnv instance; or null if no instance is provided */ public IQMakeEnv createEnv(IController controller) { if (! matches(controller)) { return null; } IQMakeEnvProvider provider; try { provider = (IQMakeEnvProvider) element.createExecutableExtension(ATTR_CLASS); } catch (CoreException e) { Activator.log("Error in class attribute of " + id, e); //$NON-NLS-1$ return null; } return provider.createEnv(controller); } /** * Checks whether an enablement expression evaluation is true. * * @param controller the controller * @return true if the provider can be used; false otherwise */ private boolean matches(IController controller) { Boolean eval = evaluation.get(); if (eval != null) { return eval.booleanValue(); } if (enablementExpression != null) { ICConfigurationDescription configuration = controller != null ? controller.getConfiguration() : null; IProject project = configuration != null ? configuration.getProjectDescription().getProject() : null; EvaluationContext evalContext = new EvaluationContext(null, project); try { if (project != null) { String[] natures = project.getDescription().getNatureIds(); evalContext.addVariable(VAR_PROJECTNATURES, Arrays.asList(natures)); } return enablementExpression.evaluate(evalContext) == EvaluationResult.TRUE; } catch (CoreException e) { Activator.log("Error while evaluating enablement expression for " + id, e); //$NON-NLS-1$ } } evaluation.set(Boolean.FALSE); return false; } }