diff options
Diffstat (limited to 'src/main/java/org/sonar')
-rw-r--r-- | src/main/java/org/sonar/cli/BootstrapLauncher.java | 99 | ||||
-rw-r--r-- | src/main/java/org/sonar/cli/ChildFirstClassLoader.java | 75 | ||||
-rw-r--r-- | src/main/java/org/sonar/cli/Launcher.java | 109 |
3 files changed, 283 insertions, 0 deletions
diff --git a/src/main/java/org/sonar/cli/BootstrapLauncher.java b/src/main/java/org/sonar/cli/BootstrapLauncher.java new file mode 100644 index 0000000..dabadcc --- /dev/null +++ b/src/main/java/org/sonar/cli/BootstrapLauncher.java @@ -0,0 +1,99 @@ +/* + * Sonar CLI + * Copyright (C) 2009 SonarSource + * dev@sonar.codehaus.org + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.cli; + +import org.sonar.batch.bootstrapper.BatchDownloader; + +import java.io.File; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.List; + +public class BootstrapLauncher { + + private static final String LAUNCHER_CLASS_NAME = "org.sonar.cli.Launcher"; + + private String[] args; + + public static void main(String[] args) throws Exception { + new BootstrapLauncher(args).bootstrap(); + } + + public BootstrapLauncher(String[] args) { + this.args = args; + } + + public void bootstrap() throws Exception { + ClassLoader cl = getInitialClassLoader(); + + Class launcherClass = cl.loadClass(LAUNCHER_CLASS_NAME); + + Method[] methods = launcherClass.getMethods(); + Method mainMethod = null; + + for (int i = 0; i < methods.length; ++i) { + if (!("main".equals(methods[i].getName()))) { + continue; + } + + int modifiers = methods[i].getModifiers(); + + if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { + continue; + } + + if (methods[i].getReturnType() != Void.TYPE) { + continue; + } + + Class[] paramTypes = methods[i].getParameterTypes(); + if (paramTypes.length != 1) { + continue; + } + if (paramTypes[0] != String[].class) { + continue; + } + mainMethod = methods[i]; + break; + } + + if (mainMethod == null) { + throw new NoSuchMethodException(LAUNCHER_CLASS_NAME + ":main(String[] args)"); + } + + Thread.currentThread().setContextClassLoader(cl); + + mainMethod.invoke(launcherClass, new Object[] { this.args }); + } + + private static ClassLoader getInitialClassLoader() throws Exception { + BatchDownloader downloader = new BatchDownloader("http://localhost:9000"); // TODO hard-coded value + List<File> files = downloader.downloadBatchFiles(new File("/tmp/sonar-boot")); + ChildFirstClassLoader classLoader = new ChildFirstClassLoader(); + for (File file : files) { + System.out.println(file); + classLoader.addFile(file); + } + // Add JAR with Sonar CLI - it's a Jar which contains this class + classLoader.addURL(BootstrapLauncher.class.getProtectionDomain().getCodeSource().getLocation()); + return classLoader; + } +} diff --git a/src/main/java/org/sonar/cli/ChildFirstClassLoader.java b/src/main/java/org/sonar/cli/ChildFirstClassLoader.java new file mode 100644 index 0000000..c6ab493 --- /dev/null +++ b/src/main/java/org/sonar/cli/ChildFirstClassLoader.java @@ -0,0 +1,75 @@ +/* + * Sonar CLI + * Copyright (C) 2009 SonarSource + * dev@sonar.codehaus.org + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.cli; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +public class ChildFirstClassLoader extends URLClassLoader { + public ChildFirstClassLoader() { + super(new URL[0]); + } + + @Override + public void addURL(URL url) { + super.addURL(url); + } + + public void addFile(File file) { + try { + addURL(file.toURI().toURL()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + /** + * Searches for classes using child-first strategy. + */ + @Override + protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + // First, check if the class has already been loaded + Class<?> c = findLoadedClass(name); + // If not loaded, search the local (child) resources + if (c == null) { + try { + c = findClass(name); + } catch (ClassNotFoundException e) { + // ignore + } + } + // If we could not find it, delegate to parent + // Note that we don't attempt to catch any ClassNotFoundException + if (c == null) { + if (getParent() != null) { + c = getParent().loadClass(name); + } else { + c = getSystemClassLoader().loadClass(name); + } + } + if (resolve) { + resolveClass(c); + } + return c; + } +} diff --git a/src/main/java/org/sonar/cli/Launcher.java b/src/main/java/org/sonar/cli/Launcher.java new file mode 100644 index 0000000..ef502b7 --- /dev/null +++ b/src/main/java/org/sonar/cli/Launcher.java @@ -0,0 +1,109 @@ +/* + * Sonar CLI + * Copyright (C) 2009 SonarSource + * dev@sonar.codehaus.org + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.cli; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.joran.spi.JoranException; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.io.IOUtils; +import org.slf4j.LoggerFactory; +import org.sonar.api.platform.Environment; +import org.sonar.api.utils.SonarException; +import org.sonar.batch.Batch; +import org.sonar.batch.bootstrapper.ProjectDefinition; +import org.sonar.batch.bootstrapper.Reactor; + +import java.io.*; +import java.util.Properties; + +public class Launcher { + + private String[] args; + + public static void main(String[] args) throws Exception { + new Launcher(args).execute(); + } + + public Launcher(String[] args) { + this.args = args; + } + + public void execute() throws Exception { + initLogging(); + ProjectDefinition project = defineProject(new File(args[0])); + Reactor reactor = new Reactor(project); + Batch batch = new Batch(getInitialConfiguration(), Environment.ANT, reactor); // TODO environment + batch.execute(); + } + + private void initLogging() { + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + JoranConfigurator jc = new JoranConfigurator(); + jc.setContext(context); + context.reset(); + InputStream input = Batch.class.getResourceAsStream("/org/sonar/batch/logback.xml"); + // System.setProperty("ROOT_LOGGER_LEVEL", getLog().isDebugEnabled() ? "DEBUG" : "INFO"); + System.setProperty("ROOT_LOGGER_LEVEL", "INFO"); + try { + jc.doConfigure(input); + + } catch (JoranException e) { + throw new SonarException("can not initialize logging", e); + + } finally { + IOUtils.closeQuietly(input); + } + } + + private ProjectDefinition defineProject(File file) { + File baseDir = file.getParentFile(); + File workDir = new File(baseDir, ".sonar"); + Properties properties = new Properties(); + try { + properties.load(new FileInputStream(file)); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + ProjectDefinition definition = new ProjectDefinition(baseDir, workDir, properties); + // TODO for some reason it can't be relative + definition.addSourceDir(new File(baseDir, "src").getAbsolutePath()); // TODO hard-coded value + // TODO definition.addTestDir(path); + // TODO definition.addBinaryDir(path); + // TODO definition.addLibrary(path); + + System.out.println(baseDir); + + return definition; + } + + private Configuration getInitialConfiguration() { + // TODO + return new SystemConfiguration(); + } + +} |