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.plugins;
021    
022    import java.io.File;
023    import java.io.IOException;
024    import java.net.URI;
025    import java.util.ArrayList;
026    import java.util.List;
027    
028    import org.apache.commons.io.FileUtils;
029    import org.apache.commons.lang.StringUtils;
030    import org.sonar.api.ServerComponent;
031    import org.sonar.api.utils.HttpDownloader;
032    import org.sonar.api.utils.Logs;
033    import org.sonar.api.utils.SonarException;
034    import org.sonar.server.platform.DefaultServerFileSystem;
035    import org.sonar.updatecenter.common.Plugin;
036    import org.sonar.updatecenter.common.Release;
037    import org.sonar.updatecenter.common.Version;
038    
039    public class PluginDownloader implements ServerComponent {
040    
041      private UpdateCenterClient center;
042      private HttpDownloader downloader;
043      private File downloadDir;
044    
045      public PluginDownloader(UpdateCenterClient center, HttpDownloader downloader, DefaultServerFileSystem fileSystem) {
046        this.center = center;
047        this.downloader = downloader;
048        this.downloadDir = fileSystem.getDownloadedPluginsDir();
049        try {
050          FileUtils.forceMkdir(downloadDir);
051    
052        } catch (IOException e) {
053          throw new SonarException("Fail to create the plugin downloads directory: " + downloadDir, e);
054        }
055      }
056    
057      /**
058       * for unit tests
059       */
060      PluginDownloader(UpdateCenterClient center, HttpDownloader downloader, File downloadDir) {
061        this.center = center;
062        this.downloader = downloader;
063        this.downloadDir = downloadDir;
064      }
065    
066      public void cancelDownloads() {
067        try {
068          if (downloadDir.exists()) {
069            FileUtils.cleanDirectory(downloadDir);
070          }
071    
072        } catch (IOException e) {
073          throw new SonarException("Fail to clean the plugin downloads directory: " + downloadDir, e);
074        }
075      }
076    
077      public boolean hasDownloads() {
078        return getDownloads().size() > 0;
079      }
080    
081      public List<String> getDownloads() {
082        List<String> names = new ArrayList<String>();
083        List<File> files = (List<File>) FileUtils.listFiles(downloadDir, new String[] { "jar" }, false);
084        for (File file : files) {
085          names.add(file.getName());
086        }
087        return names;
088      }
089    
090      public void download(String pluginKey, Version version) {
091        Plugin plugin = center.getCenter().getPlugin(pluginKey);
092        if (plugin == null) {
093          String message = "This plugin does not exist: " + pluginKey;
094          Logs.INFO.warn(message);
095          throw new SonarException(message);
096        }
097    
098        Release release = plugin.getRelease(version);
099        if (release == null || StringUtils.isBlank(release.getDownloadUrl())) {
100          String message = "This release can not be installed: " + pluginKey + ", version " + version;
101          Logs.INFO.warn(message);
102          throw new SonarException(message);
103        }
104    
105        try {
106          URI uri = new URI(release.getDownloadUrl());
107          String filename = StringUtils.substringAfterLast(uri.getPath(), "/");
108          downloader.download(uri, new File(downloadDir, filename));
109    
110        } catch (Exception e) {
111          String message = "Fail to download the plugin (" + pluginKey + ", version " + version + ") from " + release.getDownloadUrl();
112          Logs.INFO.warn(message, e);
113          throw new SonarException(message, e);
114        }
115      }
116    }