Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to Marvelution under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Marvelution licenses this file to you 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 com.marvelution.jira.plugins.sonar.streams;
import static com.atlassian.streams.spi.StandardStreamsFilterOption.ACTIVITY_KEY;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.marvelution.jira.plugins.sonar.streams.SonarStreamsFilterOptionProvider.SONAR_BASE_ACTIVITY_OBJECT_TYPE;
import static com.marvelution.jira.plugins.sonar.streams.SonarStreamsFilterOptionProvider.SONAR_ACTIVITY_OBJECT_TYPE;
import static com.marvelution.jira.plugins.sonar.streams.SonarStreamsFilterOptionProvider.SONAR_ASSOCIATION_KEY;
import static com.marvelution.jira.plugins.sonar.streams.SonarStreamsFilterOptionProvider.SONAR_SERVER_KEY;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.sonar.wsclient.Sonar;
import org.sonar.wsclient.services.Event;
import org.sonar.wsclient.services.EventQuery;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager;
import com.atlassian.plugin.webresource.UrlMode;
import com.atlassian.plugin.webresource.WebResourceUrlProvider;
import com.atlassian.sal.api.message.I18nResolver;
import com.atlassian.streams.api.ActivityRequest;
import com.atlassian.streams.api.ActivityVerb;
import com.atlassian.streams.api.StreamsEntry;
import com.atlassian.streams.api.StreamsException;
import com.atlassian.streams.api.StreamsFeed;
import com.atlassian.streams.api.UserProfile;
import com.atlassian.streams.api.common.ImmutableNonEmptyList;
import com.atlassian.streams.api.common.Option;
import com.atlassian.streams.spi.CancellableTask;
import com.atlassian.streams.spi.CancelledException;
import com.atlassian.streams.spi.Filters;
import com.atlassian.streams.spi.StandardStreamsFilterOption;
import com.atlassian.streams.spi.StreamsActivityProvider;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.marvelution.jira.plugins.sonar.services.associations.SonarAssociation;
import com.marvelution.jira.plugins.sonar.services.associations.SonarAssociationManager;
import com.marvelution.jira.plugins.sonar.services.servers.SonarClientFactory;
import com.marvelution.jira.plugins.sonar.services.servers.SonarServer;
import com.marvelution.jira.plugins.sonar.services.servers.SonarServerManager;
import com.marvelution.jira.plugins.sonar.utils.PluginHelper;
/**
* Hudson specific implementation of the {@link StreamsActivityProvider}
*
* @author Mark Rekveld
* @since 4.2.0
*/
public class SonarStreamsActivityProvider implements StreamsActivityProvider {
private final Logger logger = Logger.getLogger(SonarStreamsActivityProvider.class);
private final I18nResolver i18nResolver;
private final ProjectManager projectManager;
private final SonarAssociationManager associationManager;
private final SonarServerManager serverManager;
private final SonarClientFactory clientFactory;
private final WebResourceUrlProvider webResourceUrlProvider;
/**
* Constructor
*
* @param i18nResolver the {@link I18nResolver} implementation
* @param projectManager the {@link ProjectManager} implementation
* @param associationManager the {@link SonarAssociationManager} implementation
* @param serverManager the {@link SonarServerManager} implementation
* @param clientFactory the {@link SonarClientFactory} implementation
* @param webResourceUrlProvider the {@link WebResourceUrlProvider} implementation
*/
public SonarStreamsActivityProvider(I18nResolver i18nResolver, ProjectManager projectManager, SonarAssociationManager associationManager,
SonarServerManager serverManager, SonarClientFactory clientFactory,
WebResourceUrlProvider webResourceUrlProvider) {
this.i18nResolver = checkNotNull(i18nResolver, "i18nResolver");
this.projectManager = checkNotNull(projectManager, "projectManager");
this.associationManager = checkNotNull(associationManager, "associationManager");
this.serverManager = checkNotNull(serverManager, "serverManager");
this.clientFactory = checkNotNull(clientFactory, "clientFactory");
this.webResourceUrlProvider = checkNotNull(webResourceUrlProvider, "webResourceUrlProvider");
}
/**
* {@inheritDoc}
*/
@Override
public CancellableTask getActivityFeed(final ActivityRequest activityRequest) throws StreamsException {
return new CancellableTask() {
final AtomicBoolean cancelled = new AtomicBoolean(false);
/**
* {@inheritDoc}
*/
@Override
public StreamsFeed call() throws Exception {
Set eventTypes = getActivityFilters(activityRequest);
Set associations = Sets.newHashSet();
Project project = null;
if ((project = getProjectFromFilter(activityRequest)) != null) {
logger.debug("Only getting the associations related to project with key: " + project.getKey());
associations.addAll(associationManager.getAssociations(project));
} else {
if (activityRequest.getProviderFilters().containsKey(SONAR_ASSOCIATION_KEY)) {
logger.debug("Only getting events from associations in the provider filter");
for (Integer associationId : getAssociationFilters(activityRequest)) {
associations.add(associationManager.getAssociation(associationId));
}
}
if (activityRequest.getProviderFilters().containsKey(SONAR_SERVER_KEY)) {
logger.debug("Only getting events from servers in the provider filter");
for (Integer serverId : getServerFilters(activityRequest)) {
SonarServer server = serverManager.getServer(serverId);
associations.addAll(Arrays.asList(server.getAssociations()));
}
}
if (!activityRequest.getProviderFilters().containsKey(SONAR_ASSOCIATION_KEY)
&& !activityRequest.getProviderFilters().containsKey(SONAR_SERVER_KEY)) {
logger.debug("Getting events from all associations");
associations.addAll(associationManager.getAssociations());
}
}
EventQuery query = new EventQuery();
if (!eventTypes.contains(EventType.ALL)) {
Set categories = Sets.newHashSet();
for (EventType type : eventTypes) {
categories.add(type.category);
}
query.setCategories(categories.toArray(new String[categories.size()]));
}
List streamsEntries = Lists.newArrayList();
for (SonarAssociation association : associations) {
// Make sure we only have the servers that the administrator allows in the activity streams
if (association.getSonarServer().isIncludeInStreams()) {
Sonar client = clientFactory.create(association.getSonarServer());
query.setResourceKey(association.getSonarProject());
if (cancelled.get()) {
throw new CancelledException();
}
try {
logger.debug("Connecting to server " + association.getSonarServer().getHost()
+ " to get all the activities matching the query");
for (Event event : client.findAll(query)) {
streamsEntries.add(toStreamsEntry(association, event));
}
} catch (Exception e) {
logger.error("Failed to execute query: " + association.getSonarServer().getHost()
+ query.getUrl());
throw new StreamsException("Failed to get activities from assocaition "
+ association.getSonarServer().getName() + " / " + association.getSonarProject(), e);
}
} else {
logger.debug("Skipping server '" + association.getSonarServer().getName()
+ "' in activity streams");
}
}
return new StreamsFeed(i18nResolver.getText("streams.sonar.feed.title"), streamsEntries,
Option. none());
}
/**
* {@inheritDoc}
*/
@Override
public Result cancel() {
cancelled.set(true);
return Result.CANCELLED;
}
};
}
/**
* Transform a given {@link Event} to a {@link StreamsEntry}
*
* @param from the {@link Event} to transform
* @return the {@link StreamsEntry}
* @throws URISyntaxException
*/
private StreamsEntry toStreamsEntry(SonarAssociation association, final Event event) throws URISyntaxException {
URI eventUri = new URI(association.getSonarServer().getHost() + "/dashboard/index/"
+ association.getSonarProject());
StreamsEntry.ActivityObject activityObject =
new StreamsEntry.ActivityObject(StreamsEntry.ActivityObject.params().id("")
.alternateLinkUri(eventUri).activityObjectType(SONAR_ACTIVITY_OBJECT_TYPE));
ActivityVerb verb =
SonarStreamsFilterOptionProvider.getActivityVerbForEvent(EventType.getEventTypeForEvent(event));
final StreamsEntry.Renderer renderer = new SonarStreamsEntryRenderer(i18nResolver, event);
UserProfile.Builder builder = new UserProfile.Builder("sonar").fullName("Sonar")
.profilePictureUri(Option.option(
URI.create(webResourceUrlProvider.getStaticPluginResourceUrl(PluginHelper.getPluginKey()
+ ":sonar-stream-resources", "sonarsource-wave.png", UrlMode.ABSOLUTE))));
return new StreamsEntry(StreamsEntry
.params()
.id(eventUri)
.postedDate(new DateTime(event.getDate()))
.authors(ImmutableNonEmptyList.of(builder.build()))
.addActivityObject(activityObject)
.verb(verb)
.addLink(
URI.create(webResourceUrlProvider.getStaticPluginResourceUrl(PluginHelper.getPluginKey()
+ ":sonar-stream-resources", "puzzle-piece.gif", UrlMode.ABSOLUTE)),
StreamsActivityProvider.ICON_LINK_REL,
Option.none(String.class))
.alternateLinkUri(eventUri)
.renderer(renderer)
.applicationType("Sonar"), i18nResolver);
}
/**
* Get a single {@link Project} from the Standard Streams Filter
*
* @param activityRequest the {@link ActivityRequest}
* @return the {@link Project}, may be null
*/
private Project getProjectFromFilter(ActivityRequest activityRequest) {
Set keys =
Filters.getIsValues(activityRequest.getStandardFilters().get(StandardStreamsFilterOption.PROJECT_KEY));
if (keys != null && keys.size() == 1) {
try {
return projectManager.getProjectObjByKey(keys.toArray(new String[keys.size()])[0]);
} catch (Exception e) {
// Ignore this. Just invalid configuration
}
}
return null;
}
/**
* Get all the active Association Ids from the {@link ActivityRequest}
*
* @param activityRequest the {@link ActivityRequest} to get all the association Ids from
* @return the {@link Set} of association ids
*/
private Set getAssociationFilters(ActivityRequest activityRequest) {
Set ids = Sets.newHashSet();
for (SonarAssociation association : associationManager.getAssociations()) {
ids.add(association.getID());
}
return getFiltersFromActivityRequest(activityRequest, SONAR_ASSOCIATION_KEY, ids, toInteger);
}
/**
* Get all the active Server Ids from the {@link ActivityRequest}
*
* @param activityRequest the {@link ActivityRequest} to get all the server Ids from
* @return the {@link Set} of server ids
*/
private Set getServerFilters(ActivityRequest activityRequest) {
Set ids = Sets.newHashSet();
for (SonarServer server : serverManager.getServers()) {
ids.add(server.getID());
}
return getFiltersFromActivityRequest(activityRequest, SONAR_SERVER_KEY, ids, toInteger);
}
/**
* Get all the active {@link EventType} objects from the {@link ActivityRequest}
*
* @param activityRequest the {@link ActivityRequest} to get the options from
* @return the {@link Set} of {@link EventType} objects
*/
private Set getActivityFilters(ActivityRequest activityRequest) {
return getFiltersFromActivityRequest(activityRequest, ACTIVITY_KEY, Sets.newHashSet(EventType.values()),
toSonarActivity);
}
/**
* Get the Provider Filter values out of the {@link ActivityRequest}
*
* @param activityRequest the {@link ActivityRequest}
* @param key the key of the Provider Filter
* @param allItems the default all items for the provider
* @param transformer the {@link Function} to use to transform the {@link String} value to the needed value
* @return {@link Set} of transformed values
*/
private Set getFiltersFromActivityRequest(ActivityRequest activityRequest, String key, Set allItems,
Function transformer) {
Set isStringValues = Filters.getIsValues(activityRequest.getProviderFilters().get(key));
Set notStringValues = Filters.getNotValues(activityRequest.getProviderFilters().get(key));
Set isValues;
if (isStringValues.isEmpty()) {
isValues = ImmutableSet.copyOf(allItems);
} else {
isValues = ImmutableSet.copyOf(Iterables.transform(isStringValues, transformer));
}
Set notValues = ImmutableSet.copyOf(Iterables.transform(notStringValues, transformer));
return Sets.difference(isValues, notValues);
}
/**
* Converts an activity option key (in the form of a String) to an {@link EventType}.
*/
private static final Function toSonarActivity = new Function() {
/**
* {@inheritDoc}
*/
@Override
public EventType apply(String option) {
String hudsonActivity = option.substring((SONAR_BASE_ACTIVITY_OBJECT_TYPE + ":").length());
return EventType.valueOf(hudsonActivity.replace(" ", "_").toUpperCase());
}
};
/**
* Converts an activity option key (in the form of a String) to an {@link Integer}.
*/
private static final Function toInteger = new Function() {
/**
* {@inheritDoc}
*/
@Override
public Integer apply(String option) {
return Integer.parseInt(option);
}
};
}