*/
package org.sonar.server.computation.ws;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
-import java.util.ArrayList;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentDtoFunctions;
import org.sonar.server.computation.log.CeLogging;
import org.sonar.server.computation.log.LogFileRef;
import org.sonarqube.ws.WsCe;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.FluentIterable.from;
+
/**
* Converts {@link CeActivityDto} and {@link CeQueueDto} to the protobuf objects
* used to write WS responses (see ws-ce.proto in module sonar-ws)
this.system2 = system2;
}
- public List<WsCe.Task> formatQueue(DbSession dbSession, List<CeQueueDto> dtos) {
- ComponentCache cache = new ComponentCache(dbSession);
- List<WsCe.Task> result = new ArrayList<>();
- for (CeQueueDto dto : dtos) {
- result.add(formatQueue(dto, cache));
- }
- return result;
+ public Iterable<WsCe.Task> formatQueue(DbSession dbSession, List<CeQueueDto> dtos) {
+ ComponentDtoCache cache = new ComponentDtoCache(dbSession, ceQueueDtoToComponentUuids(dtos));
+ return from(dtos)
+ .transform(new CeQueueDtoToTask(cache));
}
public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto dto) {
- return formatQueue(dto, new ComponentCache(dbSession));
+ return formatQueue(dto, new ComponentDtoCache(dbSession, dto.getComponentUuid()));
}
- private WsCe.Task formatQueue(CeQueueDto dto, ComponentCache componentCache) {
+ private WsCe.Task formatQueue(CeQueueDto dto, ComponentDtoCache componentDtoCache) {
WsCe.Task.Builder builder = WsCe.Task.newBuilder();
builder.setId(dto.getUuid());
builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
builder.setLogs(ceLogging.getFile(LogFileRef.from(dto)).isPresent());
if (dto.getComponentUuid() != null) {
builder.setComponentId(dto.getComponentUuid());
- buildComponent(builder, componentCache.get(dto.getComponentUuid()));
+ buildComponent(builder, componentDtoCache.get(dto.getComponentUuid()));
}
if (dto.getSubmitterLogin() != null) {
builder.setSubmitterLogin(dto.getSubmitterLogin());
}
public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto) {
- return formatActivity(dto, new ComponentCache(dbSession));
+ return formatActivity(dto, new ComponentDtoCache(dbSession, dto.getComponentUuid()));
}
- public List<WsCe.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
- ComponentCache cache = new ComponentCache(dbSession);
- List<WsCe.Task> result = new ArrayList<>();
- for (CeActivityDto dto : dtos) {
- result.add(formatActivity(dto, cache));
- }
- return result;
+ public Iterable<WsCe.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
+ ComponentDtoCache cache = new ComponentDtoCache(dbSession, ceActivityDtoToComponentUuids(dtos));
+ return from(dtos).transform(new CeActivityDtoToTask(cache));
}
- private WsCe.Task formatActivity(CeActivityDto dto, ComponentCache componentCache) {
+ private WsCe.Task formatActivity(CeActivityDto dto, ComponentDtoCache componentDtoCache) {
WsCe.Task.Builder builder = WsCe.Task.newBuilder();
builder.setId(dto.getUuid());
builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
builder.setLogs(ceLogging.getFile(LogFileRef.from(dto)).isPresent());
if (dto.getComponentUuid() != null) {
builder.setComponentId(dto.getComponentUuid());
- buildComponent(builder, componentCache.get(dto.getComponentUuid()));
+ buildComponent(builder, componentDtoCache.get(dto.getComponentUuid()));
}
if (dto.getSnapshotId() != null) {
builder.setAnalysisId(String.valueOf(dto.getSnapshotId()));
}
}
- private class ComponentCache {
- private final DbSession dbSession;
- private final Map<String, ComponentDto> componentsByUuid = new HashMap<>();
+ private static Set<String> ceQueueDtoToComponentUuids(Iterable<CeQueueDto> dtos) {
+ return from(dtos)
+ .transform(new Function<CeQueueDto, String>() {
+ @Override
+ @Nullable
+ public String apply(@Nonnull CeQueueDto input) {
+ return input.getComponentUuid();
+ }
+ })
+ .filter(notNull())
+ .toSet();
+ }
+
+ private static Set<String> ceActivityDtoToComponentUuids(Iterable<CeActivityDto> dtos) {
+ return from(dtos)
+ .transform(new Function<CeActivityDto, String>() {
+ @Override
+ @Nullable
+ public String apply(@Nonnull CeActivityDto input) {
+ return input.getComponentUuid();
+ }
+ })
+ .filter(notNull())
+ .toSet();
+ }
+
+ private class ComponentDtoCache {
+ private final Map<String, ComponentDto> componentsByUuid;
- ComponentCache(DbSession dbSession) {
- this.dbSession = dbSession;
+ public ComponentDtoCache(DbSession dbSession, Set<String> uuids) {
+ this.componentsByUuid = from(dbClient.componentDao().selectByUuids(dbSession, uuids)).uniqueIndex(ComponentDtoFunctions.toUuid());
+ }
+
+ public ComponentDtoCache(DbSession dbSession, String uuid) {
+ Optional<ComponentDto> componentDto = dbClient.componentDao().selectByUuid(dbSession, uuid);
+ this.componentsByUuid = componentDto.isPresent() ? ImmutableMap.of(uuid, componentDto.get()) : Collections.<String, ComponentDto>emptyMap();
}
@CheckForNull
- ComponentDto get(String uuid) {
- ComponentDto dto = componentsByUuid.get(uuid);
- if (dto == null) {
- Optional<ComponentDto> opt = dbClient.componentDao().selectByUuid(dbSession, uuid);
- if (opt.isPresent()) {
- dto = opt.get();
- componentsByUuid.put(uuid, dto);
- }
+ ComponentDto get(@Nullable String uuid) {
+ if (uuid == null) {
+ return null;
}
- return dto;
+ return componentsByUuid.get(uuid);
}
}
}
return system2.now() - startedAt;
}
+
+ private final class CeActivityDtoToTask implements Function<CeActivityDto, WsCe.Task> {
+ private final ComponentDtoCache cache;
+
+ public CeActivityDtoToTask(ComponentDtoCache cache) {
+ this.cache = cache;
+ }
+
+ @Override
+ @Nonnull
+ public WsCe.Task apply(@Nonnull CeActivityDto input) {
+ return formatActivity(input, cache);
+ }
+ }
+
+ private final class CeQueueDtoToTask implements Function<CeQueueDto, WsCe.Task> {
+ private final ComponentDtoCache cache;
+
+ public CeQueueDtoToTask(ComponentDtoCache cache) {
+ this.cache = cache;
+ }
+
+ @Override
+ @Nonnull
+ public WsCe.Task apply(@Nonnull CeQueueDto input) {
+ return formatQueue(input, cache);
+ }
+ }
}