001/* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar 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 * Sonar 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 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020package org.sonar.server.startup; 021 022import com.google.common.collect.Lists; 023import com.google.common.collect.Ordering; 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026import org.sonar.api.utils.TimeProfiler; 027import org.sonar.api.web.Dashboard; 028import org.sonar.api.web.DashboardTemplate; 029import org.sonar.core.dashboard.ActiveDashboardDao; 030import org.sonar.core.dashboard.ActiveDashboardDto; 031import org.sonar.core.dashboard.DashboardDao; 032import org.sonar.core.dashboard.DashboardDto; 033import org.sonar.core.dashboard.WidgetDto; 034import org.sonar.core.dashboard.WidgetPropertyDto; 035import org.sonar.core.template.LoadedTemplateDao; 036import org.sonar.core.template.LoadedTemplateDto; 037 038import java.io.Serializable; 039import java.util.Date; 040import java.util.List; 041import java.util.Map.Entry; 042 043/** 044 * @since 2.13 045 */ 046public final class RegisterNewDashboards { 047 private static final Logger LOG = LoggerFactory.getLogger(RegisterNewDashboards.class); 048 static final String DEFAULT_DASHBOARD_NAME = "Dashboard"; 049 050 private final List<DashboardTemplate> dashboardTemplates; 051 private final DashboardDao dashboardDao; 052 private final ActiveDashboardDao activeDashboardDao; 053 private final LoadedTemplateDao loadedTemplateDao; 054 055 public RegisterNewDashboards(DashboardTemplate[] dashboardTemplatesArray, DashboardDao dashboardDao, 056 ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) { 057 this.dashboardTemplates = Lists.newArrayList(dashboardTemplatesArray); 058 this.dashboardDao = dashboardDao; 059 this.activeDashboardDao = activeDashboardDao; 060 this.loadedTemplateDao = loadedTemplateDao; 061 } 062 063 public void start() { 064 TimeProfiler profiler = new TimeProfiler().start("Register dashboards"); 065 066 List<DashboardDto> registeredDashboards = Lists.newArrayList(); 067 for (DashboardTemplate template : dashboardTemplates) { 068 if (shouldRegister(template.getName())) { 069 Dashboard dashboard = template.createDashboard(); 070 DashboardDto dto = register(template.getName(), dashboard); 071 if ((dto != null) && (dashboard.isActivated())) { 072 registeredDashboards.add(dto); 073 } 074 } 075 } 076 077 activate(registeredDashboards); 078 079 profiler.stop(); 080 } 081 082 protected void activate(List<DashboardDto> loadedDashboards) { 083 int nextOrderIndex = activeDashboardDao.selectMaxOrderIndexForNullUser() + 1; 084 085 for (DashboardDto dashboardDto : new DashboardOrdering().sortedCopy(loadedDashboards)) { 086 activate(dashboardDto, nextOrderIndex++); 087 } 088 } 089 090 private void activate(DashboardDto dashboardDto, int index) { 091 ActiveDashboardDto activeDashboardDto = new ActiveDashboardDto() 092 .setDashboardId(dashboardDto.getId()) 093 .setOrderIndex(index); 094 activeDashboardDao.insert(activeDashboardDto); 095 096 LOG.info("New dashboard '" + dashboardDto.getName() + "' registered"); 097 } 098 099 protected DashboardDto register(String name, Dashboard dashboard) { 100 DashboardDto dto = null; 101 if (dashboardDao.selectGlobalDashboard(name) == null) { 102 dto = createDtoFromExtension(name, dashboard); 103 dashboardDao.insert(dto); 104 } 105 // and save the fact that is has now already been loaded 106 loadedTemplateDao.insert(new LoadedTemplateDto(name, LoadedTemplateDto.DASHBOARD_TYPE)); 107 return dto; 108 } 109 110 protected DashboardDto createDtoFromExtension(String name, Dashboard dashboard) { 111 Date now = new Date(); 112 113 DashboardDto dashboardDto = new DashboardDto() 114 .setName(name) 115 .setDescription(dashboard.getDescription()) 116 .setColumnLayout(dashboard.getLayout().getCode()) 117 .setShared(true) 118 .setGlobal(dashboard.isGlobal()) 119 .setCreatedAt(now) 120 .setUpdatedAt(now); 121 122 for (int columnIndex = 1; columnIndex <= dashboard.getLayout().getColumns(); columnIndex++) { 123 List<Dashboard.Widget> widgets = dashboard.getWidgetsOfColumn(columnIndex); 124 for (int rowIndex = 1; rowIndex <= widgets.size(); rowIndex++) { 125 Dashboard.Widget widget = widgets.get(rowIndex - 1); 126 WidgetDto widgetDto = new WidgetDto() 127 .setKey(widget.getId()) 128 .setColumnIndex(columnIndex) 129 .setRowIndex(rowIndex) 130 .setConfigured(true) 131 .setCreatedAt(now) 132 .setUpdatedAt(now); 133 dashboardDto.addWidget(widgetDto); 134 135 for (Entry<String, String> property : widget.getProperties().entrySet()) { 136 WidgetPropertyDto propDto = new WidgetPropertyDto() 137 .setKey(property.getKey()) 138 .setValue(property.getValue()); 139 widgetDto.addWidgetProperty(propDto); 140 } 141 } 142 } 143 return dashboardDto; 144 } 145 146 protected boolean shouldRegister(String dashboardName) { 147 return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.DASHBOARD_TYPE, dashboardName) == 0; 148 } 149 150 private static class DashboardOrdering extends Ordering<DashboardDto> implements Serializable { 151 private static final long serialVersionUID = 0; 152 153 @Override 154 public int compare(DashboardDto left, DashboardDto right) { 155 String leftName = (left == null) ? null : left.getName(); 156 String rightName = (right == null) ? null : right.getName(); 157 158 // the default dashboard must be the first one to be activated 159 if (DEFAULT_DASHBOARD_NAME.equals(leftName)) { 160 return -1; 161 } 162 if (DEFAULT_DASHBOARD_NAME.equals(rightName)) { 163 return 1; 164 } 165 166 return Ordering.natural().nullsLast().compare(leftName, rightName); 167 } 168 } 169}