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 */
020 package org.sonar.server.startup;
021
022 import com.google.common.collect.Lists;
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025 import org.sonar.api.utils.TimeProfiler;
026 import org.sonar.api.web.Dashboard;
027 import org.sonar.api.web.DashboardTemplate;
028 import org.sonar.core.dashboard.*;
029 import org.sonar.core.template.LoadedTemplateDao;
030 import org.sonar.core.template.LoadedTemplateDto;
031
032 import java.util.Collections;
033 import java.util.Comparator;
034 import java.util.Date;
035 import java.util.List;
036 import java.util.Map.Entry;
037
038 /**
039 * @since 2.13
040 */
041 public final class RegisterNewDashboards {
042
043 private static final Logger LOG = LoggerFactory.getLogger(RegisterNewDashboards.class);
044 static final String DEFAULT_DASHBOARD_NAME = "Dashboard";
045
046 private List<DashboardTemplate> dashboardTemplates;
047 private DashboardDao dashboardDao;
048 private ActiveDashboardDao activeDashboardDao;
049 private LoadedTemplateDao loadedTemplateDao;
050
051 public RegisterNewDashboards(DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) {
052 this(new DashboardTemplate[]{}, dashboardDao, activeDashboardDao, loadedTemplateDao);
053 }
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) {
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 Collections.sort(loadedDashboards, new DashboardComparator());
085 for (DashboardDto dashboardDto : loadedDashboards) {
086 activate(dashboardDto, nextOrderIndex++);
087 }
088 }
089
090 private void activate(DashboardDto dashboardDto, int index) {
091 ActiveDashboardDto activeDashboardDto = new ActiveDashboardDto();
092 activeDashboardDto.setDashboardId(dashboardDto.getId());
093 activeDashboardDto.setOrderIndex(index);
094 activeDashboardDao.insert(activeDashboardDto);
095 LOG.info("New dashboard '" + dashboardDto.getName() + "' registered");
096 }
097
098 protected DashboardDto register(String name, Dashboard dashboard) {
099 DashboardDto dto = null;
100 if (dashboardDao.selectGlobalDashboard(name) == null) {
101 dto = createDtoFromExtension(name, dashboard);
102 dashboardDao.insert(dto);
103 }
104 // and save the fact that is has now already been loaded
105 loadedTemplateDao.insert(new LoadedTemplateDto(name, LoadedTemplateDto.DASHBOARD_TYPE));
106 return dto;
107 }
108
109 protected DashboardDto createDtoFromExtension(String name, Dashboard dashboard) {
110 Date now = new Date();
111 DashboardDto dashboardDto = new DashboardDto();
112 dashboardDto.setName(name);
113 dashboardDto.setDescription(dashboard.getDescription());
114 dashboardDto.setColumnLayout(dashboard.getLayout().getCode());
115 dashboardDto.setShared(true);
116 dashboardDto.setCreatedAt(now);
117 dashboardDto.setUpdatedAt(now);
118
119 for (int columnIndex = 1; columnIndex <= dashboard.getLayout().getColumns(); columnIndex++) {
120 List<Dashboard.Widget> widgets = dashboard.getWidgetsOfColumn(columnIndex);
121 for (int rowIndex = 1; rowIndex <= widgets.size(); rowIndex++) {
122 Dashboard.Widget widget = widgets.get(rowIndex - 1);
123 WidgetDto widgetDto = new WidgetDto();
124 widgetDto.setKey(widget.getId());
125 widgetDto.setColumnIndex(columnIndex);
126 widgetDto.setRowIndex(rowIndex);
127 widgetDto.setConfigured(true);
128 widgetDto.setCreatedAt(now);
129 widgetDto.setUpdatedAt(now);
130 dashboardDto.addWidget(widgetDto);
131
132 for (Entry<String, String> property : widget.getProperties().entrySet()) {
133 WidgetPropertyDto propDto = new WidgetPropertyDto();
134 propDto.setKey(property.getKey());
135 propDto.setValue(property.getValue());
136 widgetDto.addWidgetProperty(propDto);
137 }
138 }
139
140 }
141 return dashboardDto;
142 }
143
144 protected boolean shouldRegister(String dashboardName) {
145 return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.DASHBOARD_TYPE, dashboardName) == 0;
146 }
147
148 protected static class DashboardComparator implements Comparator<DashboardDto> {
149 public int compare(DashboardDto d1, DashboardDto d2) {
150 // the default dashboard must be the first one to be activated
151 if (d1.getName().equals(DEFAULT_DASHBOARD_NAME)) {
152 return -1;
153 }
154 if (d2.getName().equals(DEFAULT_DASHBOARD_NAME)) {
155 return 1;
156 }
157 return d1.getName().compareTo(d2.getName());
158 }
159 }
160
161 }