001/* 002 * SonarQube 003 * Copyright (C) 2009-2017 SonarSource SA 004 * mailto:info AT sonarsource DOT com 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api.resources; 021 022import com.google.common.annotations.Beta; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.LinkedHashMap; 027import java.util.LinkedHashSet; 028import java.util.List; 029import java.util.Map; 030import java.util.Objects; 031import java.util.function.Predicate; 032import java.util.stream.Collectors; 033import org.sonar.api.ce.ComputeEngineSide; 034import org.sonar.api.server.ServerSide; 035 036import static java.util.Collections.unmodifiableList; 037import static java.util.Collections.unmodifiableMap; 038import static java.util.Collections.unmodifiableSet; 039import static java.util.Objects.requireNonNull; 040 041/** 042 * @since 2.14 043 */ 044@Beta 045@ServerSide 046@ComputeEngineSide 047public class ResourceTypes { 048 049 public static final Predicate<ResourceType> AVAILABLE_FOR_FILTERS = input -> input != null && input.getBooleanProperty("supportsMeasureFilters"); 050 051 private final Map<String, ResourceTypeTree> treeByQualifier; 052 private final Map<String, ResourceType> typeByQualifier; 053 private final Collection<ResourceType> orderedTypes; 054 private final Collection<ResourceType> rootTypes; 055 056 public ResourceTypes() { 057 this(new ResourceTypeTree[0]); 058 } 059 060 public ResourceTypes(ResourceTypeTree[] trees) { 061 requireNonNull(trees); 062 063 Map<String, ResourceTypeTree> treeMap = new LinkedHashMap<>(); 064 Map<String, ResourceType> typeMap = new LinkedHashMap<>(); 065 Collection<ResourceType> rootsSet = new LinkedHashSet<>(); 066 067 for (ResourceTypeTree tree : trees) { 068 rootsSet.add(tree.getRootType()); 069 for (ResourceType type : tree.getTypes()) { 070 if (treeMap.containsKey(type.getQualifier())) { 071 throw new IllegalStateException("Qualifier " + type.getQualifier() + " is defined in several trees"); 072 } 073 treeMap.put(type.getQualifier(), tree); 074 typeMap.put(type.getQualifier(), type); 075 } 076 } 077 treeByQualifier = unmodifiableMap(new LinkedHashMap<>(treeMap)); 078 typeByQualifier = unmodifiableMap(new LinkedHashMap<>(typeMap)); 079 rootTypes = unmodifiableList(new ArrayList<>(rootsSet)); 080 081 List<ResourceType> mutableOrderedTypes = new ArrayList<>(); 082 ResourceType view = null; 083 ResourceType subView = null; 084 for (ResourceType resourceType : typeByQualifier.values()) { 085 if (Qualifiers.VIEW.equals(resourceType.getQualifier())) { 086 view = resourceType; 087 } else if (Qualifiers.SUBVIEW.equals(resourceType.getQualifier())) { 088 subView = resourceType; 089 } else { 090 mutableOrderedTypes.add(resourceType); 091 } 092 } 093 if (subView != null) { 094 mutableOrderedTypes.add(0, subView); 095 } 096 if (view != null) { 097 mutableOrderedTypes.add(0, view); 098 } 099 100 orderedTypes = unmodifiableSet(new LinkedHashSet<>(mutableOrderedTypes)); 101 } 102 103 public ResourceType get(String qualifier) { 104 ResourceType type = typeByQualifier.get(qualifier); 105 return type != null ? type : ResourceType.builder(qualifier).build(); 106 } 107 108 public Collection<ResourceType> getAll() { 109 return typeByQualifier.values(); 110 } 111 112 public Collection<ResourceType> getAllOrdered() { 113 return orderedTypes; 114 } 115 116 public Collection<ResourceType> getRoots() { 117 return rootTypes; 118 } 119 120 public Collection<ResourceType> getAll(Predicate<ResourceType> predicate) { 121 return typeByQualifier.values().stream() 122 .filter(predicate) 123 .collect(Collectors.toList()); 124 } 125 126 public Collection<ResourceType> getAllWithPropertyKey(String propertyKey) { 127 return typeByQualifier.values() 128 .stream() 129 .filter(Objects::nonNull) 130 .filter(input -> input.hasProperty(propertyKey)) 131 .collect(Collectors.toList()); 132 } 133 134 public Collection<ResourceType> getAllWithPropertyValue(String propertyKey, String propertyValue) { 135 return typeByQualifier.values() 136 .stream() 137 .filter(Objects::nonNull) 138 .filter(input -> Objects.equals(propertyValue, input.getStringProperty(propertyKey))) 139 .collect(Collectors.toList()); 140 } 141 142 public Collection<ResourceType> getAllWithPropertyValue(String propertyKey, boolean propertyValue) { 143 return typeByQualifier.values() 144 .stream() 145 .filter(Objects::nonNull) 146 .filter(input -> input.getBooleanProperty(propertyKey) == propertyValue) 147 .collect(Collectors.toList()); 148 } 149 150 public List<String> getChildrenQualifiers(String qualifier) { 151 ResourceTypeTree tree = getTree(qualifier); 152 if (tree != null) { 153 return tree.getChildren(qualifier); 154 } 155 return Collections.emptyList(); 156 } 157 158 public List<ResourceType> getChildren(String qualifier) { 159 return getChildrenQualifiers(qualifier) 160 .stream() 161 .map(typeByQualifier::get) 162 .collect(Collectors.toList()); 163 } 164 165 public List<String> getLeavesQualifiers(String qualifier) { 166 ResourceTypeTree tree = getTree(qualifier); 167 if (tree != null) { 168 return tree.getLeaves(); 169 } 170 return Collections.emptyList(); 171 } 172 173 public ResourceTypeTree getTree(String qualifier) { 174 return treeByQualifier.get(qualifier); 175 } 176 177 public ResourceType getRoot(String qualifier) { 178 return getTree(qualifier).getRootType(); 179 } 180 181}