001/* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2014 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube 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 * SonarQube 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 com.google.common.base.Function; 024import com.google.common.base.Objects; 025import com.google.common.base.Preconditions; 026import com.google.common.base.Predicate; 027import com.google.common.collect.Collections2; 028import com.google.common.collect.ImmutableList; 029import com.google.common.collect.ImmutableMap; 030import com.google.common.collect.Lists; 031import com.google.common.collect.Maps; 032import com.google.common.collect.Sets; 033import org.sonar.api.server.ServerSide; 034 035import javax.annotation.Nullable; 036 037import java.util.Collection; 038import java.util.Collections; 039import java.util.List; 040import java.util.Map; 041 042/** 043 * @since 2.14 044 */ 045@Beta 046@ServerSide 047public class ResourceTypes { 048 049 public static final Predicate<ResourceType> AVAILABLE_FOR_FILTERS = new Predicate<ResourceType>() { 050 @Override 051 public boolean apply(@Nullable ResourceType input) { 052 return input != null && input.getBooleanProperty("supportsMeasureFilters"); 053 } 054 }; 055 056 private final Map<String, ResourceTypeTree> treeByQualifier; 057 private final Map<String, ResourceType> typeByQualifier; 058 private final Collection<ResourceType> rootTypes; 059 060 public ResourceTypes() { 061 this(new ResourceTypeTree[0]); 062 } 063 064 public ResourceTypes(ResourceTypeTree[] trees) { 065 Preconditions.checkNotNull(trees); 066 067 Map<String, ResourceTypeTree> treeMap = Maps.newHashMap(); 068 Map<String, ResourceType> typeMap = Maps.newLinkedHashMap(); 069 Collection<ResourceType> rootsSet = Sets.newHashSet(); 070 071 for (ResourceTypeTree tree : trees) { 072 rootsSet.add(tree.getRootType()); 073 for (ResourceType type : tree.getTypes()) { 074 if (treeMap.containsKey(type.getQualifier())) { 075 throw new IllegalStateException("Qualifier " + type.getQualifier() + " is defined in several trees"); 076 } 077 treeMap.put(type.getQualifier(), tree); 078 typeMap.put(type.getQualifier(), type); 079 } 080 } 081 treeByQualifier = ImmutableMap.copyOf(treeMap); 082 typeByQualifier = ImmutableMap.copyOf(typeMap); 083 rootTypes = ImmutableList.copyOf(rootsSet); 084 } 085 086 public ResourceType get(String qualifier) { 087 ResourceType type = typeByQualifier.get(qualifier); 088 return type != null ? type : ResourceType.builder(qualifier).build(); 089 } 090 091 public Collection<ResourceType> getAll() { 092 return typeByQualifier.values(); 093 } 094 095 public Collection<ResourceType> getRoots() { 096 return rootTypes; 097 } 098 099 public Collection<ResourceType> getAll(Predicate<ResourceType> predicate) { 100 return Collections2.filter(typeByQualifier.values(), predicate); 101 } 102 103 private static class PropertyKeyPredicate implements Predicate<ResourceType> { 104 private final String propertyKey; 105 106 public PropertyKeyPredicate(String propertyKey) { 107 this.propertyKey = propertyKey; 108 } 109 110 @Override 111 public boolean apply(@Nullable ResourceType input) { 112 return input != null && input.hasProperty(propertyKey); 113 } 114 } 115 116 public Collection<ResourceType> getAllWithPropertyKey(final String propertyKey) { 117 return Collections2.filter(typeByQualifier.values(), new PropertyKeyPredicate(propertyKey)); 118 } 119 120 private static class StringPropertyValuePredicate implements Predicate<ResourceType> { 121 private final String propertyValue; 122 private final String propertyKey; 123 124 public StringPropertyValuePredicate(String propertyValue, String propertyKey) { 125 this.propertyValue = propertyValue; 126 this.propertyKey = propertyKey; 127 } 128 129 @Override 130 public boolean apply(@Nullable ResourceType input) { 131 return input != null && Objects.equal(propertyValue, input.getStringProperty(propertyKey)); 132 } 133 } 134 135 public Collection<ResourceType> getAllWithPropertyValue(final String propertyKey, final String propertyValue) { 136 return Collections2.filter(typeByQualifier.values(), new StringPropertyValuePredicate(propertyValue, propertyKey)); 137 } 138 139 private static class BooleanPropertyValuePredicate implements Predicate<ResourceType> { 140 private final String propertyKey; 141 private final boolean propertyValue; 142 143 public BooleanPropertyValuePredicate(String propertyKey, boolean propertyValue) { 144 this.propertyKey = propertyKey; 145 this.propertyValue = propertyValue; 146 } 147 148 @Override 149 public boolean apply(@Nullable ResourceType input) { 150 return input != null && input.getBooleanProperty(propertyKey) == propertyValue; 151 } 152 } 153 154 public Collection<ResourceType> getAllWithPropertyValue(final String propertyKey, final boolean propertyValue) { 155 return Collections2.filter(typeByQualifier.values(), new BooleanPropertyValuePredicate(propertyKey, propertyValue)); 156 } 157 158 public List<String> getChildrenQualifiers(String qualifier) { 159 ResourceTypeTree tree = getTree(qualifier); 160 if (tree != null) { 161 return tree.getChildren(qualifier); 162 } 163 return Collections.emptyList(); 164 } 165 166 public List<ResourceType> getChildren(String qualifier) { 167 return Lists.transform(getChildrenQualifiers(qualifier), new Function<String, ResourceType>() { 168 @Override 169 public ResourceType apply(String s) { 170 return typeByQualifier.get(s); 171 } 172 }); 173 } 174 175 public List<String> getLeavesQualifiers(String qualifier) { 176 ResourceTypeTree tree = getTree(qualifier); 177 if (tree != null) { 178 return tree.getLeaves(); 179 } 180 return Collections.emptyList(); 181 } 182 183 public ResourceTypeTree getTree(String qualifier) { 184 return treeByQualifier.get(qualifier); 185 } 186 187 public ResourceType getRoot(String qualifier) { 188 return getTree(qualifier).getRootType(); 189 } 190 191}