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