qualifiers.CLA=Files
qualifiers.UTS=Unit Test Files
+qualifiers.all.TRK=All Projects
+qualifiers.all.VW=All Views
+qualifiers.all.DEV=All Developers
#------------------------------------------------------------------------------
#
reviews.filtered_by.to=To date
+#------------------------------------------------------------------------------
+#
+# ENTITIES PAGE
+#
+#------------------------------------------------------------------------------
+
+entities.cols.name=Name
+entities.cols.description=Description
+entities.cols.key=Key
+entities.cols.links=Links
+
+
#------------------------------------------------------------------------------
#
# COMPARISON
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
-import com.google.common.collect.*;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Lists;
import org.sonar.api.BatchExtension;
import org.sonar.api.ServerExtension;
import org.sonar.api.batch.InstantiationStrategy;
import javax.annotation.concurrent.Immutable;
+
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
/**
private List<ResourceType> types;
private ListMultimap<String, String> relations;
+ private ResourceType root;
private ResourceTypeTree(Builder builder) {
this.types = ImmutableList.copyOf(builder.types);
this.relations = ImmutableListMultimap.copyOf(builder.relations);
+ this.root = builder.root;
}
public List<ResourceType> getTypes() {
return relations.get(qualifier);
}
+ public ResourceType getRootType() {
+ return root;
+ }
+
public List<String> getLeaves() {
return ImmutableList.copyOf(Collections2.filter(relations.values(), new Predicate<String>() {
public boolean apply(String qualifier) {
public static final class Builder {
private List<ResourceType> types = Lists.newArrayList();
private ListMultimap<String, String> relations = ArrayListMultimap.create();
+ private ResourceType root;
private Builder() {
}
}
public ResourceTypeTree build() {
+ Collection<String> children = relations.values();
+ for (ResourceType type : types) {
+ if (!children.contains(type)) {
+ root = type;
+ break;
+ }
+ }
return new ResourceTypeTree(this);
}
}
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import javax.annotation.Nullable;
+
import java.util.Collection;
import java.util.Collections;
import java.util.List;
private final Map<String, ResourceTypeTree> treeByQualifier;
private final Map<String, ResourceType> typeByQualifier;
+ private final Collection<ResourceType> rootTypes;
public ResourceTypes(ResourceTypeTree[] trees) {
Preconditions.checkNotNull(trees);
Map<String, ResourceTypeTree> treeMap = Maps.newHashMap();
Map<String, ResourceType> typeMap = Maps.newLinkedHashMap();
+ Collection<ResourceType> rootsSet = Sets.newHashSet();
for (ResourceTypeTree tree : trees) {
+ rootsSet.add(tree.getRootType());
for (ResourceType type : tree.getTypes()) {
if (treeMap.containsKey(type.getQualifier())) {
throw new IllegalStateException("Qualifier " + type.getQualifier() + " is defined in several trees");
}
treeByQualifier = ImmutableMap.copyOf(treeMap);
typeByQualifier = ImmutableMap.copyOf(typeMap);
+ rootTypes = ImmutableList.copyOf(rootsSet);
}
public ResourceType get(String qualifier) {
return typeByQualifier.values();
}
+ public Collection<ResourceType> getRoots() {
+ return rootTypes;
+ }
+
public Collection<ResourceType> getAll(Predicate<ResourceType> predicate) {
return Collections2.filter(typeByQualifier.values(), predicate);
}
.addRelations("DIR", "UTS")
.build();
-
@Test
public void getTypes() {
assertThat(tree.getTypes().size(), is(4));
assertThat(tree.getChildren("FIL").size(), is(0));
}
+ @Test
+ public void getRoot() {
+ assertThat(tree.getRootType(), is(ResourceType.builder("TRK").build()));
+ }
+
@Test
public void getLeaves() {
assertThat(tree.getLeaves().size(), is(2));
public class ResourceTypesTest {
private ResourceTypeTree viewsTree = ResourceTypeTree.builder()
- .addType(ResourceType.builder(Qualifiers.VIEW).setProperty("supportsMeasureFilters", "true").build())
- .addType(ResourceType.builder(Qualifiers.SUBVIEW).build())
- .addRelations(Qualifiers.VIEW, Qualifiers.SUBVIEW)
- .addRelations(Qualifiers.SUBVIEW, Qualifiers.PROJECT)
- .build();
+ .addType(ResourceType.builder(Qualifiers.VIEW).setProperty("supportsMeasureFilters", "true").build())
+ .addType(ResourceType.builder(Qualifiers.SUBVIEW).build())
+ .addRelations(Qualifiers.VIEW, Qualifiers.SUBVIEW)
+ .addRelations(Qualifiers.SUBVIEW, Qualifiers.PROJECT)
+ .build();
private ResourceTypeTree defaultTree = ResourceTypeTree.builder()
- .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("supportsMeasureFilters", "true").build())
- .addType(ResourceType.builder(Qualifiers.DIRECTORY).build())
- .addType(ResourceType.builder(Qualifiers.FILE).build())
- .addRelations(Qualifiers.PROJECT, Qualifiers.DIRECTORY)
- .addRelations(Qualifiers.DIRECTORY, Qualifiers.FILE)
- .build();
+ .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("supportsMeasureFilters", "true").build())
+ .addType(ResourceType.builder(Qualifiers.DIRECTORY).build())
+ .addType(ResourceType.builder(Qualifiers.FILE).build())
+ .addRelations(Qualifiers.PROJECT, Qualifiers.DIRECTORY)
+ .addRelations(Qualifiers.DIRECTORY, Qualifiers.FILE)
+ .build();
- private ResourceTypes types = new ResourceTypes(new ResourceTypeTree[]{viewsTree, defaultTree});
+ private ResourceTypes types = new ResourceTypes(new ResourceTypeTree[] {viewsTree, defaultTree});
@Test
public void get() {
assertThat(qualifiers(types.getAll())).containsOnly(Qualifiers.PROJECT, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.VIEW, Qualifiers.SUBVIEW);
}
+ @Test
+ public void getRoots() {
+ assertThat(qualifiers(types.getRoots())).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW);
+ }
+
@Test
public void getAll_predicate() {
Collection<ResourceType> forFilters = types.getAll(ResourceTypes.AVAILABLE_FOR_FILTERS);
@Test(expected = IllegalStateException.class)
public void failOnDuplicatedQualifier() {
ResourceTypeTree tree1 = ResourceTypeTree.builder()
- .addType(ResourceType.builder("foo").build())
- .build();
+ .addType(ResourceType.builder("foo").build())
+ .build();
ResourceTypeTree tree2 = ResourceTypeTree.builder()
- .addType(ResourceType.builder("foo").build())
- .build();
+ .addType(ResourceType.builder("foo").build())
+ .build();
- new ResourceTypes(new ResourceTypeTree[]{tree1, tree2});
+ new ResourceTypes(new ResourceTypeTree[] {tree1, tree2});
}
static Collection<String> qualifiers(Collection<ResourceType> types) {
return getContainer().getComponentByType(componentType);
}
- public List<MeasureFilterRow> executeMeasureFilter(Map<String,Object> map, @Nullable Long userId) throws ParseException {
+ public List<MeasureFilterRow> executeMeasureFilter(Map<String, Object> map, @Nullable Long userId) throws ParseException {
return get(MeasureFilterEngine.class).execute(map, userId);
}
return get(ResourceTypes.class).getAll();
}
+ public Collection<ResourceType> getResourceRootTypes() {
+ return get(ResourceTypes.class).getRoots();
+ }
+
public ResourceType getResourceType(String qualifier) {
return get(ResourceTypes.class).get(qualifier);
}
public void ruleSeverityChanged(int parentProfileId, int activeRuleId, int oldSeverityId, int newSeverityId, String userName) {
getProfilesManager().ruleSeverityChanged(parentProfileId, activeRuleId, RulePriority.values()[oldSeverityId],
- RulePriority.values()[newSeverityId], userName);
+ RulePriority.values()[newSeverityId], userName);
}
public void ruleDeactivated(int parentProfileId, int deactivatedRuleId, String userName) {
// notifier is null when creating the administrator in the migration script 011.
if (notifier != null) {
notifier.onNewUser(NewUserHandler.Context.builder()
- .setLogin(fields.get("login"))
- .setName(fields.get("name"))
- .setEmail(fields.get("email"))
- .build());
+ .setLogin(fields.get("login"))
+ .setName(fields.get("name"))
+ .setEmail(fields.get("email"))
+ .build());
}
}
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Sonar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+class EntitiesController < ApplicationController
+
+ SECTION=Navigation::SECTION_HOME
+
+ def index
+ require_parameters :qualifier
+ @qualifier = params[:qualifier]
+ bad_request("The 'qualifier' parameter is not valid. It must reference a root type.") unless Project.root_qualifiers.include?(@qualifier)
+
+
+ @filter = MeasureFilter.new
+ @filter.criteria = params.merge({'qualifiers' => [@qualifier], 'cols' => ['name', 'description', 'key', 'links']})
+ @filter.enable_default_display
+ @filter.execute(self, :user => current_user)
+ end
+
+end
\ No newline at end of file
java_facade.deleteResourceTree(project.id)
end
end
+
+ def self.root_qualifiers()
+ @root_types ||=
+ begin
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().getResourceRootTypes().map {|type| type.getQualifier()}
+ end
+ end
def project
root||self
--- /dev/null
+<% content_for :script do %>
+ <script>
+ function removeUrlAttr(url, attribute_key) {
+ var regexp = new RegExp("&?" + attribute_key + "=([^&]$|[^&]*)", "g");
+ return url.replace(regexp, '');
+ }
+ function reloadParameters(params) {
+ var url = decodeURI(window.location.href);
+ $j.each(params, function (key, value) {
+ url = removeUrlAttr(url, key);
+ url += '&' + key + '=' + value;
+ });
+ window.location = url;
+ }
+ </script>
+<% end %>
+
+<% if @filter.results %>
+
+ <h1><%= message('qualifiers.all.' + @qualifier) -%></h1>
+ <br/>
+
+ <div id="entities">
+
+ <% if @filter.security_exclusions %>
+ <p class="notes"><%= message('results_not_display_due_to_security') -%></p>
+ <% end %>
+
+ <%
+ display_favourites = logged_in?
+ colspan = 4
+ colspan += 1 if display_favourites
+ %>
+
+ <table class="data" id="entities-table">
+ <thead>
+ <tr>
+ <% if display_favourites %>
+ <th class="thin"></th>
+ <% end %>
+ <th>
+ <%= link_to_function( message('entities.cols.name'), "reloadParameters({asc:'#{(!@filter.sort_asc?).to_s}', sort:'name'})") -%>
+ <% if @filter.sort_key=='name' %>
+ <%= @filter.sort_asc? ? image_tag("asc12.png") : image_tag("desc12.png") -%>
+ <% end %>
+ </th>
+ <th>
+ <%= link_to_function( message('entities.cols.description'), "reloadParameters({asc:'#{(!@filter.sort_asc?).to_s}', sort:'description'})") -%>
+ <% if @filter.sort_key=='description' %>
+ <%= @filter.sort_asc? ? image_tag("asc12.png") : image_tag("desc12.png") -%>
+ <% end %>
+ </th>
+ <th class="right">
+ <%= link_to_function( message('entities.cols.key'), "reloadParameters({asc:'#{(!@filter.sort_asc?).to_s}', sort:'key'})") -%>
+ <% if @filter.sort_key=='key' %>
+ <%= @filter.sort_asc? ? image_tag("asc12.png") : image_tag("desc12.png") -%>
+ <% end %>
+ </th>
+ <th class="right">
+ <%= message('entities.cols.links') -%>
+ </th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <% @filter.results.each do |result| %>
+ <tr class="<%= cycle 'even', 'odd' -%>">
+ <% if display_favourites %>
+ <td class="thin"><%= link_to_favourite(result.snapshot.resource) -%></td>
+ <% end %>
+ <td class="nowrap">
+ <%= qualifier_icon(result.snapshot)-%> <%= link_to(result.snapshot.resource.name(true), {:controller => 'dashboard', :id => result.snapshot.resource_id}, :title => result.snapshot.resource.key) -%>
+ </td>
+ <td>
+ <%= h result.snapshot.resource.description -%>
+ </td>
+ <td class="nowrap right">
+ <span class='small'><%= result.snapshot.resource.kee -%></span>
+ </td>
+ <td class="nowrap right">
+ <%
+ if result.links
+ result.links.select { |link| link.href.start_with?('http') }.each do |link|
+ %>
+ <%= link_to(image_tag(link.icon, :alt => link.name), link.href, :class => 'nolink', :popup => true) unless link.custom? -%>
+ <%
+ end
+ end
+ %>
+ </td>
+ </tr>
+ <% end %>
+
+ <% if @filter.results.empty? %>
+ <tr class="even">
+ <td colspan="<%= colspan -%>"><%= message 'no_data' -%></td>
+ </tr>
+ <% end %>
+ </tbody>
+
+ <%= render :partial => 'utils/tfoot_pagination', :locals => {:pagination => @filter.pagination, :colspan => colspan} %>
+
+ </table>
+
+ </div>
+
+<% end %>
\ No newline at end of file
<a href="#" onclick="if (sonarRecentHistory) { sonarRecentHistory.populateRecentHistoryPanel(); }; $j('#projects-menu').toggle(); return false;" class="link-more"><%= message('layout.projects') -%></a>
<div id="projects-menu" class="dropdown-menu" style="max-width: none; display: none;" onmouseout="$j(this).hide();" onmouseover="$j(this).show();">
- <div id="recent-history">
+ <div id="recent-history" style="border-bottom: 1px solid #ccc; padding-bottom: 10px;">
<h2><%= message('layout.recent_activity') -%></h2>
<ul id="recent-history-list">
</ul>
</div>
- <div style="border-top: 1px solid #ccc; margin-top: 10px;">
+ <div>
<ul>
- <li><a href="<%= ApplicationController.root_context -%>/">Projects</a></li>
- <li><a href="<%= ApplicationController.root_context -%>/">Views</a></li>
- <li><a href="<%= ApplicationController.root_context -%>/">Developers</a></li>
+ <% Project.root_qualifiers.sort.each do |qualifier| %>
+ <li><a href="<%= ApplicationController.root_context -%>/entities?qualifier=<%= qualifier -%>"><%= message('qualifiers.all.' + qualifier) -%></a></li>
+ <% end %>
</ul>
</div>
</div>