3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.computation.taskprocessor;
22 import com.google.common.base.Function;
23 import com.google.common.base.Joiner;
24 import com.google.common.base.Optional;
25 import com.google.common.collect.ArrayListMultimap;
26 import com.google.common.collect.ImmutableMap;
27 import com.google.common.collect.Maps;
28 import com.google.common.collect.Multimap;
29 import java.util.Collection;
31 import javax.annotation.Nonnull;
32 import org.sonar.server.computation.queue.CeTask;
34 import static com.google.common.base.Preconditions.checkArgument;
35 import static com.google.common.collect.FluentIterable.from;
36 import static java.lang.String.CASE_INSENSITIVE_ORDER;
37 import static java.lang.String.format;
40 * {@link CeTaskProcessorRepository} implementation which provides access to the {@link CeTaskProcessor} existing in the
41 * PicoContainer the current object belongs to.
43 public class CeTaskProcessorRepositoryImpl implements CeTaskProcessorRepository {
44 private static final Joiner COMMA_JOINER = Joiner.on(", ");
46 private final Map<String, CeTaskProcessor> taskProcessorByCeTaskType;
48 public CeTaskProcessorRepositoryImpl(CeTaskProcessor[] taskProcessors) {
49 this.taskProcessorByCeTaskType = indexTaskProcessors(taskProcessors);
53 public Optional<CeTaskProcessor> getForCeTask(CeTask ceTask) {
54 return Optional.fromNullable(taskProcessorByCeTaskType.get(ceTask.getType()));
57 private static Map<String, CeTaskProcessor> indexTaskProcessors(CeTaskProcessor[] taskProcessors) {
58 Multimap<String, CeTaskProcessor> permissiveIndex = buildPermissiveCeTaskProcessorIndex(taskProcessors);
59 checkUniqueHandlerPerCeTaskType(permissiveIndex);
60 return ImmutableMap.copyOf(Maps.transformValues(permissiveIndex.asMap(), CeTaskProcessorCollectionToFirstElement.INSTANCE));
63 private static Multimap<String, CeTaskProcessor> buildPermissiveCeTaskProcessorIndex(CeTaskProcessor[] taskProcessors) {
64 Multimap<String, CeTaskProcessor> permissiveIndex = ArrayListMultimap.create(taskProcessors.length, 1);
65 for (CeTaskProcessor taskProcessor : taskProcessors) {
66 for (String ceTaskType : taskProcessor.getHandledCeTaskTypes()) {
67 permissiveIndex.put(ceTaskType, taskProcessor);
70 return permissiveIndex;
73 private static void checkUniqueHandlerPerCeTaskType(Multimap<String, CeTaskProcessor> permissiveIndex) {
74 for (Map.Entry<String, Collection<CeTaskProcessor>> entry : permissiveIndex.asMap().entrySet()) {
76 entry.getValue().size() == 1,
78 "There can be only one CeTaskProcessor instance registered as the processor for CeTask type %s. " +
79 "More than one found. Please fix your configuration: %s",
81 COMMA_JOINER.join(from(entry.getValue()).transform(ToClassName.INSTANCE).toSortedList(CASE_INSENSITIVE_ORDER))));
85 private enum ToClassName implements Function<Object, String> {
90 public String apply(@Nonnull Object input) {
91 return input.getClass().getName();
95 private enum CeTaskProcessorCollectionToFirstElement implements Function<Collection<CeTaskProcessor>, CeTaskProcessor> {
100 public CeTaskProcessor apply(@Nonnull Collection<CeTaskProcessor> input) {
101 return input.iterator().next();