1 package org
.argeo
.slc
.ant
;
4 import java
.util
.Vector
;
6 import org
.apache
.log4j
.AppenderSkeleton
;
7 import org
.apache
.log4j
.LogManager
;
8 import org
.apache
.log4j
.spi
.LoggingEvent
;
9 import org
.apache
.tools
.ant
.BuildEvent
;
10 import org
.apache
.tools
.ant
.Project
;
11 import org
.argeo
.slc
.core
.process
.SlcExecution
;
12 import org
.argeo
.slc
.core
.process
.SlcExecutionNotifier
;
13 import org
.argeo
.slc
.core
.process
.SlcExecutionStep
;
14 import org
.argeo
.slc
.ws
.process
.WebServiceSlcExecutionNotifier
;
15 import org
.springframework
.context
.ApplicationContext
;
16 import org
.springframework
.context
.support
.AbstractApplicationContext
;
18 public class SlcExecutionBuildListener
extends AppenderSkeleton
implements
19 ProjectRelatedBuildListener
{
20 public static final String ANT_TYPE
= "org.apache.tools.ant";
21 public static final String SLC_ANT_TYPE
= "org.argeo.slc.ant";
23 public static final String REF_SLC_EXECUTION
= "slcExecution";
25 private Project project
;
27 // to avoid stack overflow when logging for log4j
28 private boolean isLogging
= false;
30 private List
<SlcExecutionNotifier
> notifiers
= new Vector
<SlcExecutionNotifier
>();
32 private boolean currentStepNotified
= true;
35 private boolean logBeforeFirstTarget
= false;
36 private boolean firstTargetStarted
= false;
38 private boolean logTaskStartFinish
= true;
40 public void init(Project project
) {
41 if (this.project
!= null) {
42 throw new SlcAntException("Build listener already initialized");
45 this.project
= project
;
47 if (!LogManager
.getRootLogger().isAttached(this)) {
48 LogManager
.getRootLogger().addAppender(this);
51 SlcExecution slcExecution
= (SlcExecution
) project
52 .getReference(REF_SLC_EXECUTION
);
53 if (slcExecution
== null)
54 throw new SlcAntException("No SLC Execution registered.");
56 for (SlcExecutionNotifier notifier
: notifiers
) {
57 notifier
.newExecution(slcExecution
);
62 public void buildStarted(BuildEvent event
) {
65 public void buildFinished(BuildEvent event
) {
66 SlcExecution slcExecution
= getSlcExecution(event
);
67 String oldStatus
= slcExecution
.getStatus();
68 slcExecution
.setStatus(SlcExecution
.STATUS_FINISHED
);
70 for (SlcExecutionNotifier notifier
: notifiers
) {
71 notifier
.updateStatus(slcExecution
, oldStatus
, slcExecution
75 // AbstractApplicationContext context = (AbstractApplicationContext) getProject()
76 // .getReference(SlcProjectHelper.REF_ROOT_CONTEXT);
77 // if (context != null)
81 public void messageLogged(BuildEvent event
) {
85 SlcExecution slcExecution
= getSlcExecution(event
);
86 if (slcExecution
!= null) {
87 if (currentStepNotified
) {
88 slcExecution
.getSteps().add(
89 new SlcExecutionStep("LOG", event
.getMessage()));
90 notifyStep(slcExecution
, slcExecution
.currentStep());
91 currentStepNotified
= true;
93 slcExecution
.currentStep().addLog(event
.getMessage());
96 // TODO: log before initialization?
100 public void targetStarted(BuildEvent event
) {
101 if (!firstTargetStarted
)
102 firstTargetStarted
= true;
104 addLogStep(event
, "Target " + event
.getTarget().getName() + " started");
107 public void targetFinished(BuildEvent event
) {
108 addLogStep(event
, "Target " + event
.getTarget().getName() + " finished");
111 public void taskStarted(BuildEvent event
) {
115 SlcExecution slcExecution
= getSlcExecution(event
);
116 if (!currentStepNotified
) {
117 notifyStep(slcExecution
, slcExecution
.currentStep());
118 currentStepNotified
= true;
122 if (logTaskStartFinish
)
123 msg
= "Task " + event
.getTask().getTaskName() + " started";
125 slcExecution
.getSteps().add(new SlcExecutionStep("LOG", msg
));
127 currentStepNotified
= false;
130 public void taskFinished(BuildEvent event
) {
134 SlcExecution slcExecution
= getSlcExecution(event
);
135 if (!currentStepNotified
) {
137 if (logTaskStartFinish
)
138 slcExecution
.currentStep().addLog(
139 "Task " + event
.getTask().getTaskName() + " finished");
141 notifyStep(slcExecution
, slcExecution
.currentStep());
142 currentStepNotified
= true;
146 public void setNotifiers(List
<SlcExecutionNotifier
> notifiers
) {
147 this.notifiers
= notifiers
;
150 protected SlcExecution
getSlcExecution(BuildEvent event
) {
151 Project projectEvt
= event
.getProject();
152 if (!projectEvt
.equals(project
))
153 throw new SlcAntException("Event project " + projectEvt
154 + " not consistent with listener project " + project
);
156 SlcExecution slcExecution
= (SlcExecution
) project
157 .getReference(REF_SLC_EXECUTION
);
159 if (slcExecution
== null)
160 throw new SlcAntException("No SLC Execution registered.");
164 protected void addLogStep(BuildEvent event
, String msg
) {
165 SlcExecution slcExecution
= getSlcExecution(event
);
166 slcExecution
.getSteps().add(new SlcExecutionStep("LOG", msg
));
168 notifyStep(slcExecution
, slcExecution
.currentStep());
169 currentStepNotified
= true;
172 protected void notifyStep(SlcExecution slcExecution
, SlcExecutionStep step
) {
173 Vector
<SlcExecutionStep
> additionalSteps
= new Vector
<SlcExecutionStep
>();
174 additionalSteps
.add(step
);
175 notifySteps(slcExecution
, additionalSteps
);
178 protected void notifySteps(SlcExecution slcExecution
,
179 List
<SlcExecutionStep
> additionalSteps
) {
180 for (SlcExecutionNotifier notifier
: notifiers
) {
181 notifier
.addSteps(slcExecution
, additionalSteps
);
188 protected void append(LoggingEvent event
) {
190 // avoid StackOverflow if notification calls Log4j itself.
194 // FIXME: make it more generic
195 if (event
.getLoggerName().equals(
196 WebServiceSlcExecutionNotifier
.class.getName())) {
203 SlcExecution slcExecution
= (SlcExecution
) project
204 .getReference(REF_SLC_EXECUTION
);
205 if (slcExecution
!= null) {
206 if (currentStepNotified
) {
207 slcExecution
.getSteps().add(
208 new SlcExecutionStep("LOG", event
.getMessage()
210 currentStepNotified
= false;
212 slcExecution
.currentStep()
213 .addLog(event
.getMessage().toString());
215 // TODO: log before initialization?
223 protected boolean shouldLog() {
224 return logBeforeFirstTarget
|| firstTargetStarted
;
228 public void close() {
232 public boolean requiresLayout() {
236 public Project
getProject() {