/******************************************************************************* * Copyright (c) 2009, 2010 Alena Laskavaia * 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: * Alena Laskavaia - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.codan.core.model; import java.util.Collection; import java.util.Iterator; import org.eclipse.cdt.codan.core.param.BasicProblemPreference; import org.eclipse.cdt.codan.core.param.FileScopeProblemPreference; import org.eclipse.cdt.codan.core.param.IProblemPreference; import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType; import org.eclipse.cdt.codan.core.param.LaunchModeProblemPreference; import org.eclipse.cdt.codan.core.param.ListProblemPreference; import org.eclipse.cdt.codan.core.param.MapProblemPreference; import org.eclipse.cdt.codan.core.param.RootProblemPreference; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; /** * AbstractChecker that has extra methods to simplify adding problem * preferences. * Checker can produce several problems, but preferences are per problem. * Sharing preferences between problems is not supported now. */ public abstract class AbstractCheckerWithProblemPreferences extends AbstractChecker implements ICheckerWithPreferences { /** * Checker that actually has parameter must override this */ public void initPreferences(IProblemWorkingCopy problem) { getTopLevelPreference(problem); // initialize } /** * Scope preference - special preference that all file checkers should have, * it allows user to include/exclude files for this specific problem. * * @param problem - problem for which scope preference is need * @return scope problem preference, null if not defined */ public FileScopeProblemPreference getScopePreference(IProblem problem) { return getTopLevelPreference(problem).getScopePreference(); } /** * @param problem - problem for which preference is extracted * @return launch mode preference * @since 2.0 */ public LaunchModeProblemPreference getLaunchModePreference(IProblem problem) { return getTopLevelPreference(problem).getLaunchModePreference(); } /** * User can scope out some resources for this checker. Checker can use this * call to test if it should run on this resource at all or not. Test should * be done within processResource method not in enabledInContext. * This test uses user "scope" preference for the all problems that this * checker can produce. * * @param res - resource to test on * @return true if checker should report problems, fails otherwise. */ public boolean shouldProduceProblems(IResource res) { Collection<IProblem> refProblems = getRuntime().getCheckersRegistry().getRefProblems(this); for (Iterator<IProblem> iterator = refProblems.iterator(); iterator.hasNext();) { IProblem checkerProblem = iterator.next(); if (shouldProduceProblem(getProblemById(checkerProblem.getId(), res), res.getLocation())) return true; } return false; } /** * User can scope out some resources for this checker. Checker can use this * call to test if it should run on this resource at all or produce * a specific problem on this resource. Test should * be done within processResource method not in enabledInContext, or just * before printing of a problem. * This test uses user "scope" preference for the given problem. If scope is * not defined preference it returns true. * * @param problem - problem to test for * @param resource - resource to test on * * @return true if problem should be report for given resource, fails * otherwise. */ public boolean shouldProduceProblem(IProblem problem, IPath resource) { FileScopeProblemPreference scope = getScopePreference(problem); if (scope == null) return true; return scope.isInScope(resource); } @Override public void reportProblem(String problemId, IProblemLocation loc, Object... args) { if (shouldProduceProblem(getProblemById(problemId, loc.getFile()), loc.getFile().getLocation())) { super.reportProblem(problemId, loc, args); } } /** * Reports a problem * * @param pr - problem (kind) instance * @param loc - problem location * @param args - extra problem arguments * * @since 2.0 */ public void reportProblem(IProblem pr, IProblemLocation loc, Object... args) { if (shouldProduceProblem(pr, loc.getFile().getLocation())) super.reportProblem(pr.getId(), loc, args); } /** * Adds a parameter * * @param problem * - problem that has parameter * @param key * - parameter key * @param label * - parameter label - user visible * @param defaultValue * - parameter default value * @return - parameter info object */ public IProblemPreference addPreference(IProblemWorkingCopy problem, String key, String label, Object defaultValue) { MapProblemPreference map = getTopLevelPreference(problem); BasicProblemPreference info = new BasicProblemPreference(key, label, PreferenceType.typeOf(defaultValue)); map.addChildDescriptor(info); setDefaultPreferenceValue(problem, key, defaultValue); return info; } /** * Adds preference of type list of strings, list is empty by default. * * @param problem * - problem * @param key * - preference key * @param label * - preference label * @param itemLabel * @return preference instance of of the list, can be used to add default * values or set different element type * */ public ListProblemPreference addListPreference(IProblemWorkingCopy problem, String key, String label, String itemLabel) { MapProblemPreference map = getTopLevelPreference(problem); ListProblemPreference list = new ListProblemPreference(key, label); list.setChildDescriptor(new BasicProblemPreference(ListProblemPreference.COMMON_DESCRIPTOR_KEY, itemLabel, PreferenceType.TYPE_STRING)); return (ListProblemPreference) map.addChildDescriptor(list); } /** * Adds preference for the given problem with default value * * @param problem * @param pref - preference * @param defaultValue - default value of the preference * @return added preference */ public IProblemPreference addPreference(IProblemWorkingCopy problem, IProblemPreference pref, Object defaultValue) { MapProblemPreference map = getTopLevelPreference(problem); String key = pref.getKey(); pref = map.addChildDescriptor(pref); setDefaultPreferenceValue(problem, key, defaultValue); return pref; } /** * Convenience method for setting default preference value for checker that * uses "map" as top level problem preference. * * @param problem - problem for which to set default value for a preference * @param key - preference key * @param defaultValue - value of preference to be set */ protected void setDefaultPreferenceValue(IProblemWorkingCopy problem, String key, Object defaultValue) { MapProblemPreference map = getTopLevelPreference(problem); if (map.getChildValue(key) == null) map.setChildValue(key, defaultValue); } /** * Returns "map" problem preference for a give problem, if problem * has preference different than a map, it will throw ClassCastException. * If top level preference does not exist create a map preference with name * "params" * and return it. * * @param problem * @return top level preference if it is a map * @since 2.0 */ public RootProblemPreference getTopLevelPreference(IProblem problem) { RootProblemPreference map = (RootProblemPreference) problem.getPreference(); if (map == null) { map = new RootProblemPreference(); if (problem instanceof IProblemWorkingCopy) { ((IProblemWorkingCopy) problem).setPreference(map); } } return map; } /** * Returns value of the preference for the key in the top level * preference map for the given problem * * @param problem - problem for which to get the preference * @param key - preference key * @return value of the preference */ public Object getPreference(IProblem problem, String key) { return ((MapProblemPreference) problem.getPreference()).getChildValue(key); } /** * @param arg - actual problem argument * @param problem - problem kind * @param exceptionListParamId - parameter id of the parameter representing * exception list for the given argumnet * @return true if argument matches of the names in the exception list * @since 2.0 */ public boolean isFilteredArg(String arg, IProblem problem, String exceptionListParamId) { Object[] arr = (Object[]) getPreference(problem, exceptionListParamId); for (int i = 0; i < arr.length; i++) { String str = (String) arr[i]; if (arg.equals(str)) return true; } return false; } }