Java tutorial
/* * JBoss, Home of Professional Open Source * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual * contributors by the @authors tag. See the copyright.txt in the * distribution for a full listing of individual contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.maven.plugins.qstools.config; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.logging.Log; import org.apache.maven.settings.Proxy; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.context.Context; import org.codehaus.plexus.context.ContextException; import org.jboss.maven.plugins.qstools.Constants; import org.yaml.snakeyaml.Yaml; /** * @author Rafael Benevides * */ @Component(role = ConfigurationProvider.class) public class ConfigurationProvider { @Requirement private Context context; private URL configFileURL; private Log log; private MavenSession mavenSession; private Map<String, Rules> configRules = new HashMap<String, Rules>(); private void configure() throws ContextException { configFileURL = (URL) context.get(Constants.CONFIG_FILE_CONTEXT); log = (Log) context.get(Constants.LOG_CONTEXT); mavenSession = (MavenSession) context.get(Constants.MAVEN_SESSION_CONTEXT); } /** * Return the {@link Rules} which should be used for a Quickstarts/Project * * @param groupId - the groupId of the Quickstart/Project * * @return */ public Rules getQuickstartsRules(String groupId) { if (configFileURL == null) { try { configure(); } catch (ContextException e) { log.error(e.getMessage(), e); return null; } } Rules rules = configRules.get(groupId); if (rules == null) { rules = initializeConfig(groupId); } return rules; } @SuppressWarnings("unchecked") private Rules initializeConfig(String groupId) { InputStream inputStream = null; try { // Retrieve inputStream (local cache or remote) inputStream = getConfigFileInputStream(); Yaml yaml = new Yaml(); Map<String, Object> configFile = (Map<String, Object>) yaml.load(inputStream); Map<String, Object> quickstartsGroupIds = (Map<String, Object>) configFile.get("quickstarts"); List<Object> configs = (List<Object>) quickstartsGroupIds.get(groupId); if (configs == null) { Map<String, Object> defaultRulesSection = (Map<String, Object>) ((List<Object>) configFile .get("rules")).get(0); List<Object> defaultRules = new LinkedList<Object>(); defaultRules.add(defaultRulesSection); configs = defaultRules; } Rules rules = new Rules(configs); configRules.put(groupId, rules); return configRules.get(groupId); } catch (FileNotFoundException e) { log.error("FileNotFoundException", e); return null; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.error("Something bad happened when closing the inputstream", e); } } } } /** * @return * @throws FileNotFoundException * */ private InputStream getConfigFileInputStream() throws FileNotFoundException { InputStream repoStream = getCachedRepoStream(false); // if cache expired if (repoStream == null) { log.debug("Local cache file " + getLocalCacheFile() + " doesn't exist or cache has been expired"); try { log.debug("Retrieving Configuration from Remote repository " + configFileURL); repoStream = retrieveConfigurationFileFromRemoteRepository(); setCachedRepoStream(repoStream); log.debug("Forcing the use of local cache after download file without error from " + configFileURL); repoStream = getCachedRepoStream(true); } catch (Exception e) { log.warn("It was not possible to contact the repository at " + configFileURL + " . Cause " + e.getMessage()); log.warn("Falling back to cache!"); repoStream = getCachedRepoStream(true); } } return repoStream; } private InputStream getCachedRepoStream(final boolean force) throws FileNotFoundException { final String logmessage = "Local file %1s %2s used! Reason: Force:[%3b] - LastModification: %4d/%5d"; File localCacheFile = getLocalCacheFile(); if (localCacheFile.exists()) { long cachedvalidity = 1000 * Constants.CACHE_EXPIRES_SECONDS; long lastModified = localCacheFile.lastModified(); long timeSinceLastModification = System.currentTimeMillis() - lastModified; // if online, consider the cache valid until it expires if (force || timeSinceLastModification <= cachedvalidity) { log.debug(String.format(logmessage, localCacheFile, "was", force, timeSinceLastModification, cachedvalidity)); return new FileInputStream(localCacheFile); } log.debug(String.format(logmessage, localCacheFile, "was not", force, timeSinceLastModification, cachedvalidity)); } return null; } private void setCachedRepoStream(final InputStream stream) throws IOException { File localCacheFile = getLocalCacheFile(); log.debug("Content stored at " + localCacheFile); if (!localCacheFile.exists()) { localCacheFile.createNewFile(); } FileOutputStream fos = new FileOutputStream(localCacheFile); int i = 0; while ((i = stream.read()) != -1) { fos.write(i); } fos.close(); } private File getLocalCacheFile() { // Remove no word character from the repo url String repo = configFileURL.toString().replaceAll("[^a-zA-Z_0-9]", ""); return new File(System.getProperty("java.io.tmpdir"), repo + "qstools_config.yaml"); } private InputStream retrieveConfigurationFileFromRemoteRepository() throws Exception { if (configFileURL.getProtocol().startsWith("http")) { HttpGet httpGet = new HttpGet(configFileURL.toURI()); DefaultHttpClient client = new DefaultHttpClient(); configureProxy(client); HttpResponse httpResponse = client.execute(httpGet); switch (httpResponse.getStatusLine().getStatusCode()) { case 200: log.debug("Connected to repository! Getting available Stacks"); break; case 404: log.error("Failed! (Config file not found: " + configFileURL + ")"); return null; default: log.error("Failed! (server returned status code: " + httpResponse.getStatusLine().getStatusCode()); return null; } return httpResponse.getEntity().getContent(); } else if (configFileURL.getProtocol().startsWith("file")) { return new FileInputStream(new File(configFileURL.toURI())); } return null; } private void configureProxy(DefaultHttpClient client) { Proxy proxyConfig = null; if (mavenSession.getSettings().getProxies().size() > 0) { proxyConfig = mavenSession.getSettings().getProxies().get(0); } if (proxyConfig != null) { HttpHost proxy = new HttpHost(proxyConfig.getHost(), proxyConfig.getPort()); client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); String proxyUsername = proxyConfig.getUsername(); if (proxyUsername != null && !proxyUsername.isEmpty()) { String proxyPassword = proxyConfig.getPassword(); AuthScope authScope = new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(proxyUsername, proxyPassword); client.getCredentialsProvider().setCredentials(authScope, credentials); } } } }