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
;
16 public class SlcExecutionBuildListener
extends AppenderSkeleton
implements
17 ProjectRelatedBuildListener
{
18 public static final String ANT_TYPE
= "org.apache.tools.ant";
19 public static final String SLC_ANT_TYPE
= "org.argeo.slc.ant";
21 public static final String REF_SLC_EXECUTION
= "slcExecution";
23 private Project project
;
25 // to avoid stack overflow when logging for log4j
26 private boolean isLogging
= false;
28 private List
<SlcExecutionNotifier
> notifiers
= new Vector
<SlcExecutionNotifier
>();
30 private boolean currentStepNotified
= true;
33 private boolean logBeforeFirstTarget
= false;
34 private boolean firstTargetStarted
= false;
36 private boolean logTaskStartFinish
= true;
38 public void init(Project project
) {
39 if (this.project
!= null) {
40 throw new SlcAntException("Build listener already initialized");
43 this.project
= project
;
45 if (!LogManager
.getRootLogger().isAttached(this)) {
46 LogManager
.getRootLogger().addAppender(this);
49 SlcExecution slcExecution
= (SlcExecution
) project
50 .getReference(REF_SLC_EXECUTION
);
51 if (slcExecution
== null)
52 throw new SlcAntException("No SLC Execution registered.");
54 for (SlcExecutionNotifier notifier
: notifiers
) {
55 notifier
.newExecution(slcExecution
);
60 public void buildStarted(BuildEvent event
) {
63 public void buildFinished(BuildEvent event
) {
64 SlcExecution slcExecution
= getSlcExecution(event
);
65 String oldStatus
= slcExecution
.getStatus();
66 slcExecution
.setStatus(SlcExecution
.STATUS_FINISHED
);
68 for (SlcExecutionNotifier notifier
: notifiers
) {
69 notifier
.updateStatus(slcExecution
, oldStatus
, slcExecution
74 public void messageLogged(BuildEvent event
) {
78 SlcExecution slcExecution
= getSlcExecution(event
);
79 if (slcExecution
!= null) {
80 if (currentStepNotified
) {
81 slcExecution
.getSteps().add(
82 new SlcExecutionStep("LOG", event
.getMessage()));
83 notifyStep(slcExecution
, slcExecution
.currentStep());
84 currentStepNotified
= true;
86 slcExecution
.currentStep().addLog(event
.getMessage());
89 // TODO: log before initialization?
93 public void targetStarted(BuildEvent event
) {
94 if (!firstTargetStarted
)
95 firstTargetStarted
= true;
97 addLogStep(event
, "Target " + event
.getTarget().getName() + " started");
100 public void targetFinished(BuildEvent event
) {
101 addLogStep(event
, "Target " + event
.getTarget().getName() + " finished");
104 public void taskStarted(BuildEvent event
) {
108 SlcExecution slcExecution
= getSlcExecution(event
);
109 if (!currentStepNotified
) {
110 notifyStep(slcExecution
, slcExecution
.currentStep());
111 currentStepNotified
= true;
115 if (logTaskStartFinish
)
116 msg
= "Task " + event
.getTask().getTaskName() + " started";
118 slcExecution
.getSteps().add(new SlcExecutionStep("LOG", msg
));
120 currentStepNotified
= false;
123 public void taskFinished(BuildEvent event
) {
127 SlcExecution slcExecution
= getSlcExecution(event
);
128 if (!currentStepNotified
) {
130 if (logTaskStartFinish
)
131 slcExecution
.currentStep().addLog(
132 "Task " + event
.getTask().getTaskName() + " finished");
134 notifyStep(slcExecution
, slcExecution
.currentStep());
135 currentStepNotified
= true;
139 public void setNotifiers(List
<SlcExecutionNotifier
> notifiers
) {
140 this.notifiers
= notifiers
;
143 protected SlcExecution
getSlcExecution(BuildEvent event
) {
144 Project projectEvt
= event
.getProject();
145 if (!projectEvt
.equals(project
))
146 throw new SlcAntException("Event project " + projectEvt
147 + " not consistent with listener project " + project
);
149 SlcExecution slcExecution
= (SlcExecution
) project
150 .getReference(REF_SLC_EXECUTION
);
152 if (slcExecution
== null)
153 throw new SlcAntException("No SLC Execution registered.");
157 protected void addLogStep(BuildEvent event
, String msg
) {
158 SlcExecution slcExecution
= getSlcExecution(event
);
159 slcExecution
.getSteps().add(new SlcExecutionStep("LOG", msg
));
161 notifyStep(slcExecution
, slcExecution
.currentStep());
162 currentStepNotified
= true;
165 protected void notifyStep(SlcExecution slcExecution
, SlcExecutionStep step
) {
166 Vector
<SlcExecutionStep
> additionalSteps
= new Vector
<SlcExecutionStep
>();
167 additionalSteps
.add(step
);
168 notifySteps(slcExecution
, additionalSteps
);
171 protected void notifySteps(SlcExecution slcExecution
,
172 List
<SlcExecutionStep
> additionalSteps
) {
173 for (SlcExecutionNotifier notifier
: notifiers
) {
174 notifier
.addSteps(slcExecution
, additionalSteps
);
181 protected void append(LoggingEvent event
) {
183 // avoid StackOverflow if notification calls Log4j itself.
187 // FIXME: make it more generic
188 if (event
.getLoggerName().equals(
189 WebServiceSlcExecutionNotifier
.class.getName())) {
196 SlcExecution slcExecution
= (SlcExecution
) project
197 .getReference(REF_SLC_EXECUTION
);
198 if (slcExecution
!= null) {
199 if (currentStepNotified
) {
200 slcExecution
.getSteps().add(
201 new SlcExecutionStep("LOG", event
.getMessage()
203 currentStepNotified
= false;
205 slcExecution
.currentStep()
206 .addLog(event
.getMessage().toString());
208 // TODO: log before initialization?
216 protected boolean shouldLog() {
217 return logBeforeFirstTarget
|| firstTargetStarted
;
221 public void close() {
225 public boolean requiresLayout() {
229 public Project
getProject() {