/* * Copyright 2009-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.eclipse.codeassist.relevance; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IType; /** * * Abstract class containing helper methods to obtain information like enclosing * package or project for the context types, as well as uses an optional * relevance category to further prioritise rules. A relevance category is * applied to the relevance value of this rule. Categories may be useful to * avoid rule clashes, in case one rule has a higher priority than another one. * * @author Nieraj Singh * @created 2011-02-18 */ public abstract class AbstractRule implements IRelevanceRule { /** * Additional granularity for Types only. Allows rules to have different * priorities, as some rules may carry more weight than others. * */ public enum TypeRelevanceCategory { LOWEST_TYPE(1), LOW_TYPE(4), MEDIUM_TYPE(8), MEDIUM_HIGH_TYPE(12), HIGH_TYPE(16); private final double multiplier; private TypeRelevanceCategory(double multiplier) { this.multiplier = multiplier; } public double getMultiplier() { return multiplier; } public int applyCategory(int value) { return (int) getMultiplier() * value; } } /** * Returns true if an only if the relevance type is contained in the same * project as ALL other context types. If the context types includes types * from different folders, or the relevance type is in a different project * than the context types, false is returned. * * @param relevanceType * type whose relevance needs to be determined * @param contextTypes * context types where this rule is being invoked, like the * compilation unit where the relevance type is being imported * @return true if and only if the relevance type is contained in the same * project as ALL other context types */ public boolean areTypesInSameProject(IType relevanceType, IType[] contextTypes) { if (relevanceType == null || contextTypes == null || contextTypes.length == 0) { return false; } IJavaProject relevanceProject = relevanceType.getJavaProject(); if (relevanceProject == null) { return false; } for (IType cType : contextTypes) { if (!relevanceProject.equals(cType.getJavaProject())) { return false; } } return true; } /** * Returns true if an only if the relevance type is contained in the same package as ALL other * context types. If the context types includes types from different folders, or the relevance * type is in a different package than the context types, false is returned. * * @param relevanceType type whose relevance needs to be determined * @param contextTypes context types where this rule is being invoked, like the compilation unit * where the relevance type is being imported * @return true if and only if the relevance type is contained in the same package as ALL other * context types */ public boolean areTypesInSamePackage(IType relevanceType, IType[] contextTypes) { if (relevanceType == null || contextTypes == null || contextTypes.length == 0) { return false; } IPackageFragment relevancePackage = relevanceType.getPackageFragment(); if (relevancePackage == null) { return false; } for (IType cType : contextTypes) { if (!relevancePackage.equals(cType.getPackageFragment())) { return false; } } return true; } /** * Return true if and only if the relevance type and ALL the context types are in the same * compilation unit. If at least one of the context types is in a different compilation unit, or * the compilation unit of either cannot be resolved, false is returned. * * @param relevanceType * @param contextTypes * @return true if and only if the relevance type and all context types are in the same * compilation unit. False otherwise */ public boolean areTypesInSameCompilationUnit(IType relevanceType, IType[] contextTypes) { if (relevanceType == null || contextTypes == null || contextTypes.length == 0) { return false; } ICompilationUnit relevanceCompilationUnit = relevanceType .getCompilationUnit(); if (relevanceCompilationUnit != null) { for (IType contextType : contextTypes) { ICompilationUnit contextCu = contextType.getCompilationUnit(); if (!relevanceCompilationUnit.equals(contextCu)) { return false; } } return true; } return false; } /** * This returns the package fragment containing ALL the context types. If * the list of context types includes types from different packages, null is * returned. * * @param contextTypes * . Should all be part of the same compilation unit. therefore * contained in the same package * @return package fragment containing ALL the context types, or null if a * single package fragment cannot be resolved from the context types */ public IPackageFragment getContextPackageFragment(IType[] contextTypes) { if (contextTypes == null) { return null; } IPackageFragment frag = null; for (IType type : contextTypes) { IPackageFragment fragToCheck = type.getPackageFragment(); if (frag != null && !frag.equals(fragToCheck)) { return null; } frag = fragToCheck; } return frag; } public IType getFirstContextType(IType[] contextTypes) { return contextTypes != null && contextTypes.length > 0 ? contextTypes[0] : null; } }