Java tutorial
/* Copyright (C) 2013 Raquel Pau and Albert Coroleu. Walkmod is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Walkmod is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Walkmod. If not, see <http://www.gnu.org/licenses/>.*/ package org.walkmod.conf.providers; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.text.ParseException; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ivy.Ivy; import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; import org.apache.ivy.core.module.descriptor.DefaultExcludeRule; import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; import org.apache.ivy.core.module.descriptor.ExcludeRule; import org.apache.ivy.core.module.id.ArtifactId; import org.apache.ivy.core.module.id.ModuleId; import org.apache.ivy.core.module.id.ModuleRevisionId; import org.apache.ivy.core.report.ArtifactDownloadReport; import org.apache.ivy.core.report.ResolveReport; import org.apache.ivy.core.resolve.ResolveOptions; import org.apache.ivy.core.settings.IvySettings; import org.apache.ivy.plugins.matcher.ExactPatternMatcher; import org.apache.ivy.plugins.matcher.PatternMatcher; import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter; import org.walkmod.conf.ConfigurationException; import org.walkmod.conf.ConfigurationProvider; import org.walkmod.conf.entities.Configuration; import org.walkmod.conf.entities.PluginConfig; public class IvyConfigurationProvider implements ConfigurationProvider { private Configuration configuration; private boolean isOffLine; private Ivy ivy = null; private File ivyfile; private ResolveOptions resolveOptions; private DefaultModuleDescriptor md; private static final String IVY_SETTINGS_FILE = "ivysettings.xml"; private static final Log LOG = LogFactory.getLog(IvyConfigurationProvider.class); public IvyConfigurationProvider() { this(false); } public IvyConfigurationProvider(boolean isOffLine) { setOffLine(isOffLine); } @Override public void init(Configuration configuration) { this.configuration = configuration; } /** * Ivy configuration initialization * * @throws ParseException * If an error occurs when loading ivy settings file * (ivysettings.xml) * @throws IOException * If an error occurs when reading ivy settings file * (ivysettings.xml) * @throws ConfigurationException * If ivy settings file (ivysettings.xml) is not found in * classpath */ public void initIvy() throws ParseException, IOException, ConfigurationException { // creates clear ivy settings IvySettings ivySettings = new IvySettings(); File settingsFile = new File(IVY_SETTINGS_FILE); if (settingsFile.exists()) { ivySettings.load(settingsFile); } else { URL settingsURL = ClassLoader.getSystemResource(IVY_SETTINGS_FILE); if (settingsURL == null) { // file not found in System classloader, we try the current one settingsURL = this.getClass().getClassLoader().getResource(IVY_SETTINGS_FILE); // extra validation to avoid uncontrolled NullPointerException // when invoking toURI() if (settingsURL == null) throw new ConfigurationException( "Ivy settings file (" + IVY_SETTINGS_FILE + ") could not be found in classpath"); } ivySettings.load(settingsURL); } // creates an Ivy instance with settings ivy = Ivy.newInstance(ivySettings); ivyfile = File.createTempFile("ivy", ".xml"); ivyfile.deleteOnExit(); String[] confs = new String[] { "default" }; resolveOptions = new ResolveOptions().setConfs(confs); if (isOffLine) { resolveOptions = resolveOptions.setUseCacheOnly(true); } else { Map<String, Object> params = configuration.getParameters(); if (params != null) { Object value = params.get("offline"); if (value != null) { String offlineOpt = value.toString(); if (offlineOpt != null) { boolean offline = Boolean.parseBoolean(offlineOpt); if (offline) { resolveOptions = resolveOptions.setUseCacheOnly(true); } } } } } } @Override public void load() throws ConfigurationException { Collection<PluginConfig> plugins = configuration.getPlugins(); PluginConfig plugin = null; Collection<File> jarsToLoad = new LinkedList<File>(); ConfigurationException ce = null; try { if (plugins != null) { Iterator<PluginConfig> it = plugins.iterator(); initIvy(); while (it.hasNext()) { plugin = it.next(); addArtifact(plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion()); } jarsToLoad = resolveArtifacts(); URL[] urls = new URL[jarsToLoad.size()]; int i = 0; for (File jar : jarsToLoad) { urls[i] = jar.toURI().toURL(); i++; } URLClassLoader childClassLoader = new URLClassLoader(urls, configuration.getClassLoader()); configuration.setClassLoader(childClassLoader); } } catch (Exception e) { if (!(e instanceof ConfigurationException)) { if (plugin == null) { ce = new ConfigurationException("Unable to initialize ivy configuration:" + e.getMessage()); } else { ce = new ConfigurationException( "Unable to resolve the plugin: " + plugin.getGroupId() + " : " + plugin.getArtifactId() + " : " + plugin.getVersion() + ". Reason : " + e.getMessage()); } } else { ce = (ConfigurationException) e; } throw ce; } } public void addArtifact(String groupId, String artifactId, String version) throws Exception { String[] dep = null; dep = new String[] { groupId, artifactId, version }; if (md == null) { md = DefaultModuleDescriptor .newDefaultInstance(ModuleRevisionId.newInstance(dep[0], dep[1] + "-caller", "working")); } DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, ModuleRevisionId.newInstance(dep[0], dep[1], dep[2]), false, false, true); md.addDependency(dd); ExcludeRule er = new DefaultExcludeRule( new ArtifactId(new ModuleId("org.walkmod", "walkmod-core"), PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.INSTANCE, null); dd.addExcludeRule(null, er); } public Collection<File> resolveArtifacts() throws Exception { if (ivy != null) { XmlModuleDescriptorWriter.write(md, ivyfile); ResolveReport report = ivy.resolve(ivyfile.toURL(), resolveOptions); if (!report.hasError()) { ArtifactDownloadReport[] artifacts = report.getAllArtifactsReports(); Collection<File> result = new LinkedList<File>(); for (ArtifactDownloadReport item : artifacts) { result.add(item.getLocalFile()); } return result; } else { List problems = report.getAllProblemMessages(); if (problems == null || problems.isEmpty()) { throw new ConfigurationException("Ivy can not resolve the artifacts. Undefined cause"); } else { String msg = ""; Iterator it = problems.iterator(); while (it.hasNext()) { String error = it.next().toString(); LOG.warn(error); if ("".equals(msg)) { msg = error; } else { msg = msg + ";" + error; } } throw new ConfigurationException("Ivy can not resolve the artifacts. Cause: " + msg); } } } return null; } public void setOffLine(boolean isOffLine) { this.isOffLine = isOffLine; } public boolean isOffLine() { return isOffLine; } }