import org.apache.tools.ant.ProjectHelper;\r
import org.springframework.context.ApplicationContext;\r
\r
+/** @deprecated */\r
public class AntRunner {\r
private ApplicationContext context;\r
private ProjectHelper projectHelper;\r
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.Appender;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.MDC;
+import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.helper.ProjectHelper2;
import org.argeo.slc.logging.Log4jUtils;
import org.argeo.slc.runtime.SlcExecutionContext;
import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
private final static Log log = LogFactory.getLog(AntSlcApplication.class);
private Resource contextLocation;
- private ApplicationContext runtimeContext;
+ private ApplicationContext parentContext;
private Resource rootDir;
private Resource confDir;
}
// Spring initialization
- initRuntimeContext(slcExecution);
- ConfigurableApplicationContext ctx = createExecutionContext();
+ ConfigurableApplicationContext ctx = createExecutionContext(slcExecution);
// Ant coordinates
Resource script = findAntScript(slcExecution);
}
}
- protected void initRuntimeContext(SlcExecution slcExecution) {
- if (runtimeContext == null) {
+ protected ConfigurableApplicationContext createExecutionContext(
+ SlcExecution slcExecution) {
+ try {
+
+ // Find runtime definition
Resource runtimeRes = null;
String runtimeStr = slcExecution.getAttributes().get(
SlcAntConstants.EXECATTR_RUNTIME);
if (runtimeStr != null) {
+ ResourceLoader rl = new DefaultResourceLoader(getClass()
+ .getClassLoader());
try {
- ResourceLoader rl = new DefaultResourceLoader(getClass()
- .getClassLoader());
- try {
- runtimeRes = rl.getResource(runtimeStr);
- } catch (Exception e) {
- // silent
- }
- if (runtimeRes == null || !runtimeRes.exists()) {
- runtimeRes = confDir.createRelative("runtime/"
- + runtimeStr + ".xml");
- }
-
- if (runtimeRes.exists()) {
- GenericApplicationContext ctx = new GenericApplicationContext();
- XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(
- ctx);
- xmlReader.loadBeanDefinitions(runtimeRes);
-
- // Add property place holder
- PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
- ppc.setIgnoreUnresolvablePlaceholders(true);
- ctx.addBeanFactoryPostProcessor(ppc);
-
- ctx.refresh();
-
- runtimeContext = ctx;
- }
+ runtimeRes = rl.getResource(runtimeStr);
} catch (Exception e) {
- throw new SlcException(
- "Could not initialize runtime context from "
- + runtimeStr, e);
+ // silent
+ }
+ if (runtimeRes == null || !runtimeRes.exists()) {
+ runtimeRes = confDir.createRelative("runtime/" + runtimeStr
+ + ".xml");
}
}
- if (runtimeContext == null)
- log.warn("No runtime is defined.");
- }
- }
-
- protected ConfigurableApplicationContext createExecutionContext() {
- try {
+ // Find runtime independent application context definition
if (confDir != null && contextLocation == null) {
contextLocation = confDir
.createRelative("applicationContext.xml");
}
GenericApplicationContext ctx = new GenericApplicationContext(
- runtimeContext);
- if (contextLocation != null && contextLocation.exists()) {
- XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(
- ctx);
+ parentContext);
+ ctx.setDisplayName("SLC Execution #" + slcExecution.getUuid());
+
+ XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
+ if (runtimeRes != null && runtimeRes.exists())
+ xmlReader.loadBeanDefinitions(runtimeRes);
+ else
+ log.warn("No runtime context defined");
+
+ if (contextLocation != null && contextLocation.exists())
xmlReader.loadBeanDefinitions(contextLocation);
- }
+ else
+ log.warn("No runtime independent application context defined");
// Add property place holder
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
}
project.addBuildListener(new CommonsLoggingListener());
+
+ ListableBeanFactory context = (ListableBeanFactory) project
+ .getReference(SlcAntConstants.REF_ROOT_CONTEXT);
+ // Register build listeners
+ Map<String, BuildListener> listeners = context.getBeansOfType(
+ BuildListener.class, false, true);
+ for (BuildListener listener : listeners.values()) {
+ project.addBuildListener(listener);
+ }
+
+ // Register log4j appenders from context
+ MDC.put(SlcAntConstants.MDC_ANT_PROJECT, project);
+ Map<String, Appender> appenders = context.getBeansOfType(
+ Appender.class, false, true);
+ for (Appender appender : appenders.values()) {
+ LogManager.getRootLogger().addAppender(appender);
+ }
+
project.init();
addCustomTaskAndTypes(project);
}
this.workDir = workDir;
}
- public void setRuntimeContext(ApplicationContext runtimeContext) {
- this.runtimeContext = runtimeContext;
+ public void setParentContext(ApplicationContext runtimeContext) {
+ this.parentContext = runtimeContext;
}
}
import org.argeo.slc.core.structure.tree.TreeSPath;\r
import org.argeo.slc.core.structure.tree.TreeSRegistry;\r
\r
+/** @deprecated */\r
public class BasicSlcProjectHelper extends ProjectHelper2 {\r
private ApplicationContext context;\r
\r
import org.apache.tools.ant.BuildListener;\r
import org.apache.tools.ant.Project;\r
\r
+/** @deprecated */\r
public interface ProjectRelatedBuildListener extends BuildListener {\r
public Project getProject();\r
\r
package org.argeo.slc.ant;
public interface SlcAntConstants {
-
+ // ANT
/** The Ant reference to the Spring application context used. */
public static final String REF_ROOT_CONTEXT = "slcApplicationContext";
/** The Ant reference to the SLC structure registry used. */
* /org/argeo/slc/ant/typedefs.properties
*/
public static final String SLC_TYPEDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/typedefs.properties";
+ public static final String REF_SLC_EXECUTION = "slcExecution";
+
+ // SLC EXECUTION
public static final String EXECTYPE_ANT = "org.apache.tools.ant";
public static final String EXECTYPE_SLC_ANT = "org.argeo.slc.ant";
- public static final String REF_SLC_EXECUTION = "slcExecution";
public final static String EXECATTR_RUNTIME = "slc.runtime";
public final static String EXECATTR_ANT_FILE = "ant.file";
public final static String EXECATTR_ANT_TARGETS = "ant.targets";
+
+ // PROPERTIES
/** Property for the root dir (SLC root property file). */
public final static String ROOT_DIR_PROPERTY = "slc.rootDir";
/** Property for the conf dir (SLC root property file). */
/** Name of the Spring bean used by default */
public final static String DEFAULT_TEST_RUN_PROPERTY = "slc.defaultTestRun";
+ // LOG4J
+ public final static String MDC_ANT_PROJECT = "slc.ant.project";
+
}
import java.util.Vector;\r
\r
import org.apache.log4j.AppenderSkeleton;\r
+import org.apache.log4j.Level;\r
import org.apache.log4j.LogManager;\r
+import org.apache.log4j.MDC;\r
+import org.apache.log4j.Priority;\r
import org.apache.log4j.spi.LoggingEvent;\r
import org.apache.tools.ant.BuildEvent;\r
+import org.apache.tools.ant.BuildListener;\r
import org.apache.tools.ant.Project;\r
+import org.argeo.slc.core.SlcException;\r
import org.argeo.slc.core.process.SlcExecution;\r
import org.argeo.slc.core.process.SlcExecutionNotifier;\r
import org.argeo.slc.core.process.SlcExecutionStep;\r
import org.argeo.slc.ws.process.WebServiceSlcExecutionNotifier;\r
\r
public class SlcExecutionBuildListener extends AppenderSkeleton implements\r
- ProjectRelatedBuildListener {\r
- private Project project;\r
-\r
- // to avoid stack overflow when logging for log4j\r
- private boolean isLogging = false;\r
-\r
+ BuildListener {\r
private List<SlcExecutionNotifier> notifiers = new Vector<SlcExecutionNotifier>();\r
\r
private boolean currentStepNotified = true;\r
\r
// CUSTOMIZATIONS\r
+ /**\r
+ * Whether to log Ant initialization stuff before the first target has been\r
+ * called.\r
+ */\r
private boolean logBeforeFirstTarget = false;\r
+ /** Whether the first target has been called. */\r
private boolean firstTargetStarted = false;\r
\r
private boolean logTaskStartFinish = true;\r
\r
- public void init(Project project) {\r
- if (this.project != null) {\r
- throw new SlcAntException("Build listener already initialized");\r
- }\r
-\r
- this.project = project;\r
-\r
- if (!LogManager.getRootLogger().isAttached(this)) {\r
- LogManager.getRootLogger().addAppender(this);\r
- }\r
-\r
- SlcExecution slcExecution = (SlcExecution) project\r
- .getReference(SlcAntConstants.REF_SLC_EXECUTION);\r
- if (slcExecution == null)\r
- throw new SlcAntException("No SLC Execution registered.");\r
+ public SlcExecutionBuildListener() {\r
+ // Default log level\r
+ setThreshold(Level.INFO);\r
+ }\r
\r
+ public void buildStarted(BuildEvent event) {\r
+ SlcExecution slcExecution = getSlcExecution(event);\r
for (SlcExecutionNotifier notifier : notifiers) {\r
notifier.newExecution(slcExecution);\r
}\r
-\r
- }\r
-\r
- public void buildStarted(BuildEvent event) {\r
}\r
\r
public void buildFinished(BuildEvent event) {\r
notifier.updateStatus(slcExecution, oldStatus, slcExecution\r
.getStatus());\r
}\r
-\r
-// AbstractApplicationContext context = (AbstractApplicationContext) getProject()\r
-// .getReference(SlcProjectHelper.REF_ROOT_CONTEXT);\r
-// if (context != null)\r
-// context.close();\r
}\r
\r
public void messageLogged(BuildEvent event) {\r
}\r
\r
protected SlcExecution getSlcExecution(BuildEvent event) {\r
- Project projectEvt = event.getProject();\r
- if (!projectEvt.equals(project))\r
- throw new SlcAntException("Event project " + projectEvt\r
- + " not consistent with listener project " + project);\r
+ return getSlcExecution(event.getProject());\r
+ }\r
\r
+ protected SlcExecution getSlcExecution(Project project) {\r
SlcExecution slcExecution = (SlcExecution) project\r
.getReference(SlcAntConstants.REF_SLC_EXECUTION);\r
\r
\r
@Override\r
protected void append(LoggingEvent event) {\r
- if (isLogging) {\r
- // avoid StackOverflow if notification calls Log4j itself.\r
- return;\r
- }\r
- \r
- // FIXME: make it more generic\r
- if (event.getLoggerName().equals(\r
- WebServiceSlcExecutionNotifier.class.getName())) {\r
- return;\r
- }\r
-\r
- isLogging = true;\r
-\r
- try {\r
- SlcExecution slcExecution = (SlcExecution) project\r
- .getReference(SlcAntConstants.REF_SLC_EXECUTION);\r
- if (slcExecution != null) {\r
- if (currentStepNotified) {\r
- slcExecution.getSteps().add(\r
- new SlcExecutionStep("LOG", event.getMessage()\r
- .toString()));\r
- currentStepNotified = false;\r
- }\r
- slcExecution.currentStep()\r
- .addLog(event.getMessage().toString());\r
- } else {\r
- // TODO: log before initialization?\r
- }\r
- } finally {\r
- isLogging = false;\r
+ Project project = (Project) MDC.get(SlcAntConstants.MDC_ANT_PROJECT);\r
+ if (project == null)\r
+ throw new SlcException("No Ant project registered in Log4j MDC.");\r
+\r
+ SlcExecution slcExecution = getSlcExecution(project);\r
+ if (currentStepNotified) {\r
+ slcExecution.getSteps().add(\r
+ new SlcExecutionStep("LOG", event.getMessage().toString()));\r
+ currentStepNotified = false;\r
+ } else {\r
+ slcExecution.currentStep().addLog(event.getMessage().toString());\r
}\r
-\r
}\r
\r
protected boolean shouldLog() {\r
return false;\r
}\r
\r
- public Project getProject() {\r
- return project;\r
+ public void setLogBeforeFirstTarget(boolean logBeforeFirstTarget) {\r
+ this.logBeforeFirstTarget = logBeforeFirstTarget;\r
+ }\r
+\r
+ public void setLogTaskStartFinish(boolean logTaskStartFinish) {\r
+ this.logTaskStartFinish = logTaskStartFinish;\r
+ }\r
+\r
+ public void setLogLevel(String logLevel) {\r
+ setThreshold(Level.toLevel(logLevel));\r
}\r
\r
}\r
.getAbsolutePath()\r
+ File.separator));\r
slcApp.setWorkDir(new File(System.getProperty("java.io.tmpdir")));\r
- slcApp.setRuntimeContext(getContext());\r
+ slcApp.setParentContext(getContext());\r
\r
SlcExecution slcExecution = new SlcExecution();\r
slcExecution.getAttributes().put(SlcAntConstants.EXECATTR_ANT_FILE,\r