001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 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    }