001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube 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     * SonarQube 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 License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.batch.bootstrap;
021    
022    import com.google.common.collect.Lists;
023    import org.apache.commons.lang.CharUtils;
024    import org.apache.commons.lang.StringUtils;
025    import org.slf4j.Logger;
026    import org.slf4j.LoggerFactory;
027    import org.sonar.api.SonarPlugin;
028    import org.sonar.api.platform.PluginMetadata;
029    import org.sonar.core.plugins.RemotePlugin;
030    import org.sonar.core.plugins.RemotePluginFile;
031    import org.sonar.home.cache.FileCache;
032    
033    import java.io.File;
034    import java.io.IOException;
035    import java.util.Collections;
036    import java.util.List;
037    import java.util.Map;
038    
039    /**
040     * A {@link PluginsReferential} implementation that put downloaded plugins in a FS cache.
041     */
042    public class DefaultPluginsReferential implements PluginsReferential {
043    
044      private static final Logger LOG = LoggerFactory.getLogger(DefaultPluginsReferential.class);
045    
046      private ServerClient server;
047      private FileCache fileCache;
048    
049      public DefaultPluginsReferential(FileCache fileCache, ServerClient server) {
050        this.server = server;
051        this.fileCache = fileCache;
052      }
053    
054      @Override
055      public File pluginFile(final RemotePlugin remote) {
056        try {
057          final RemotePluginFile file = remote.file();
058          return fileCache.get(file.getFilename(), file.getHash(), new FileCache.Downloader() {
059            public void download(String filename, File toFile) throws IOException {
060              String url = "/deploy/plugins/" + remote.getKey() + "/" + file.getFilename();
061              if (LOG.isDebugEnabled()) {
062                LOG.debug("Download {} to {}", url, toFile.getAbsolutePath());
063              } else {
064                LOG.info("Download {}", file.getFilename());
065              }
066              server.download(url, toFile);
067            }
068          });
069    
070        } catch (Exception e) {
071          throw new IllegalStateException("Fail to download plugin: " + remote.getKey(), e);
072        }
073      }
074    
075      @Override
076      public List<RemotePlugin> pluginList() {
077        String url = "/deploy/plugins/index.txt";
078        try {
079          LOG.debug("Download index of plugins");
080          String indexContent = server.request(url);
081          String[] rows = StringUtils.split(indexContent, CharUtils.LF);
082          List<RemotePlugin> remoteLocations = Lists.newArrayList();
083          for (String row : rows) {
084            remoteLocations.add(RemotePlugin.unmarshal(row));
085          }
086          return remoteLocations;
087    
088        } catch (Exception e) {
089          throw new IllegalStateException("Fail to download plugins index: " + url, e);
090        }
091      }
092    
093      @Override
094      public Map<PluginMetadata, SonarPlugin> localPlugins() {
095        return Collections.emptyMap();
096      }
097    
098    }