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.plugins; 021 022import org.apache.commons.io.IOUtils; 023import org.slf4j.LoggerFactory; 024import org.sonar.api.Properties; 025import org.sonar.api.Property; 026import org.sonar.api.PropertyType; 027import org.sonar.api.ServerComponent; 028import org.sonar.api.config.Settings; 029import org.sonar.api.utils.HttpDownloader; 030import org.sonar.api.utils.Logs; 031import org.sonar.updatecenter.common.UpdateCenter; 032import org.sonar.updatecenter.common.UpdateCenterDeserializer; 033 034import java.io.InputStream; 035import java.net.URI; 036import java.net.URISyntaxException; 037import java.util.Date; 038 039 040/** 041 * HTTP client to load data from the remote update center hosted at http://update.sonarsource.org. 042 * 043 * @since 2.4 044 */ 045@Properties({ 046 @Property( 047 key = "sonar.updatecenter.activate", 048 defaultValue = "true", 049 name = "Enable Update Center", 050 project = false, 051 global = false, // hidden from UI 052 category = "Update Center", 053 type = PropertyType.BOOLEAN), 054 @Property( 055 key = UpdateCenterClient.URL_PROPERTY, 056 defaultValue = "http://update.sonarsource.org/update-center.properties", 057 name = "Update Center URL", 058 project = false, 059 global = false, // hidden from UI 060 category = "Update Center") 061}) 062public class UpdateCenterClient implements ServerComponent { 063 064 public static final String URL_PROPERTY = "sonar.updatecenter.url"; 065 public static final int PERIOD_IN_MILLISECONDS = 60 * 60 * 1000; 066 067 private URI uri; 068 private UpdateCenter center = null; 069 private long lastRefreshDate = 0; 070 private HttpDownloader downloader; 071 072 /** 073 * for unit tests 074 */ 075 UpdateCenterClient(HttpDownloader downloader, URI uri) { 076 this.downloader = downloader; 077 this.uri = uri; 078 Logs.INFO.info("Update center: " + uri + " (" + downloader.getProxySynthesis(uri) + ")"); 079 } 080 081 public UpdateCenterClient(HttpDownloader downloader, Settings configuration) throws URISyntaxException { 082 this(downloader, new URI(configuration.getString(URL_PROPERTY))); 083 } 084 085 public UpdateCenter getCenter() { 086 return getCenter(false); 087 } 088 089 public UpdateCenter getCenter(boolean forceRefresh) { 090 if (center == null || forceRefresh || needsRefresh()) { 091 center = download(); 092 lastRefreshDate = System.currentTimeMillis(); 093 } 094 return center; 095 } 096 097 public Date getLastRefreshDate() { 098 return lastRefreshDate > 0 ? new Date(lastRefreshDate) : null; 099 } 100 101 private boolean needsRefresh() { 102 return lastRefreshDate + PERIOD_IN_MILLISECONDS < System.currentTimeMillis(); 103 } 104 105 private UpdateCenter download() { 106 InputStream input = null; 107 try { 108 input = downloader.openStream(uri); 109 if (input != null) { 110 java.util.Properties properties = new java.util.Properties(); 111 properties.load(input); 112 return UpdateCenterDeserializer.fromProperties(properties); 113 } 114 115 } catch (Exception e) { 116 LoggerFactory.getLogger(getClass()).error("Fail to download data from update center", e); 117 118 } finally { 119 IOUtils.closeQuietly(input); 120 } 121 return null; 122 } 123}