001package org.andromda.ant.task; 002 003import java.io.FileNotFoundException; 004import java.net.URL; 005import org.andromda.core.AndroMDAServer; 006import org.andromda.core.configuration.Configuration; 007import org.apache.commons.lang.exception.ExceptionUtils; 008import org.apache.tools.ant.BuildException; 009import org.apache.tools.ant.taskdefs.MatchingTask; 010 011/** 012 * <p> 013 * This class wraps the AndroMDA model processor so that AndroMDA Server can be 014 * used as an Ant task. Represents the <code><andromda></code> custom 015 * task which can be called from an Ant build script. 016 * </p> 017 * 018 * @author Lofi Dewanto 019 */ 020public class AndroMDAServerStartTask 021 extends MatchingTask 022{ 023 /** 024 * Initialize the context class loader. 025 */ 026 static 027 { 028 initializeContextClassLoader(); 029 } 030 031 /** 032 * Stores the configuration URI. 033 */ 034 private URL configurationUri; 035 036 /** 037 * Sets the URI to the configuration file. 038 * 039 * @param configurationUri 040 */ 041 public void setConfigurationUri(final URL configurationUri) 042 { 043 this.configurationUri = configurationUri; 044 } 045 046 /** 047 * <p> 048 * Starts the AndroMDA server. 049 * </p> 050 * <p> 051 * This is the main entry point of the application when running Ant. It is 052 * called by ant whenever the surrounding task is executed (which could be 053 * multiple times). 054 * </p> 055 * 056 * @throws BuildException 057 * if something goes wrong 058 */ 059 public void execute() 060 throws BuildException 061 { 062 // Initialize before the execute as well in case we 063 // want to execute more than once 064 initializeContextClassLoader(); 065 try 066 { 067 if (this.configurationUri == null) 068 { 069 throw new BuildException("Configuration is not a valid URI --> '" + this.configurationUri + '\''); 070 } 071 072 // Create the configuration file from URI 073 final Configuration configuration = Configuration.getInstance(this.configurationUri); 074 075 // Create and start the server 076 final AndroMDAServer andromdaServer = AndroMDAServer.newInstance(); 077 if (andromdaServer != null) 078 { 079 andromdaServer.start(configuration); 080 } 081 } 082 catch (Throwable throwable) 083 { 084 final Throwable cause = ExceptionUtils.getCause(throwable); 085 if (cause != null) 086 { 087 throwable = cause; 088 } 089 if (throwable instanceof FileNotFoundException) 090 { 091 throw new BuildException("No configuration could be loaded from --> '" + configurationUri + '\''); 092 } 093 throw new BuildException(throwable); 094 } 095 finally 096 { 097 // Set the context class loader back ot its system class loaders 098 // so that any processes running after won't be trying to use 099 // the ContextClassLoader for this class. 100 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); 101 } 102 } 103 104 /** 105 * Set the context class loader so that any classes using it (the 106 * contextContextClassLoader) have access to the correct loader. 107 */ 108 private static void initializeContextClassLoader() 109 { 110 Thread.currentThread().setContextClassLoader(AndroMDAServerStartTask.class.getClassLoader()); 111 } 112}