]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.core/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java
Introduce XSLT view
[gpl/argeo-slc.git] / org.argeo.slc.core / src / main / java / org / argeo / slc / ant / SlcExecutionBuildListener.java
1 package org.argeo.slc.ant;
2
3 import java.util.List;
4 import java.util.Vector;
5
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
12 import org.argeo.slc.core.process.SlcExecution;
13 import org.argeo.slc.core.process.SlcExecutionNotifier;
14 import org.argeo.slc.core.process.SlcExecutionStep;
15 import org.argeo.slc.core.process.WebServiceSlcExecutionNotifier;
16
17 public class SlcExecutionBuildListener extends AppenderSkeleton implements
18 ProjectRelatedBuildListener {
19 public static final String ANT_TYPE = "org.apache.tools.ant";
20 public static final String SLC_ANT_TYPE = "org.argeo.slc.ant";
21
22 public static final String REF_SLC_EXECUTION = "slcExecution";
23
24 private Project project;
25
26 // to avoid stack overflow when logging for log4j
27 private boolean isLogging = false;
28
29 private List<SlcExecutionNotifier> notifiers = new Vector<SlcExecutionNotifier>();
30
31 private boolean currentStepNotified = true;
32
33 // CUSTOMIZATIONS
34 private boolean logBeforeFirstTarget = false;
35 private boolean firstTargetStarted = false;
36
37 private boolean logTaskStartFinish = true;
38
39 public void init(Project project) {
40 if (this.project != null) {
41 throw new SlcAntException("Build listener already initialized");
42 }
43
44 this.project = project;
45
46 if (!LogManager.getRootLogger().isAttached(this)) {
47 LogManager.getRootLogger().addAppender(this);
48 }
49
50 SlcExecution slcExecution = (SlcExecution) project
51 .getReference(REF_SLC_EXECUTION);
52 if (slcExecution == null)
53 throw new SlcAntException("No SLC Execution registered.");
54
55 for (SlcExecutionNotifier notifier : notifiers) {
56 notifier.newExecution(slcExecution);
57 }
58
59 }
60
61 public void buildStarted(BuildEvent event) {
62 }
63
64 public void buildFinished(BuildEvent event) {
65 SlcExecution slcExecution = getSlcExecution(event);
66 String oldStatus = slcExecution.getStatus();
67 slcExecution.setStatus(SlcExecution.STATUS_FINISHED);
68
69 for (SlcExecutionNotifier notifier : notifiers) {
70 notifier.updateStatus(slcExecution, oldStatus, slcExecution
71 .getStatus());
72 }
73 }
74
75 public void messageLogged(BuildEvent event) {
76 if (!shouldLog())
77 return;
78
79 SlcExecution slcExecution = getSlcExecution(event);
80 if (slcExecution != null) {
81 if (currentStepNotified) {
82 slcExecution.getSteps().add(
83 new SlcExecutionStep("LOG", event.getMessage()));
84 notifyStep(slcExecution, slcExecution.currentStep());
85 currentStepNotified = true;
86 } else {
87 slcExecution.currentStep().addLog(event.getMessage());
88 }
89 } else {
90 // TODO: log before initialization?
91 }
92 }
93
94 public void targetStarted(BuildEvent event) {
95 if (!firstTargetStarted)
96 firstTargetStarted = true;
97
98 addLogStep(event, "Target " + event.getTarget().getName() + " started");
99 }
100
101 public void targetFinished(BuildEvent event) {
102 addLogStep(event, "Target " + event.getTarget().getName() + " finished");
103 }
104
105 public void taskStarted(BuildEvent event) {
106 if (!shouldLog())
107 return;
108
109 SlcExecution slcExecution = getSlcExecution(event);
110 if (!currentStepNotified) {
111 notifyStep(slcExecution, slcExecution.currentStep());
112 currentStepNotified = true;
113 }
114
115 String msg = null;
116 if (logTaskStartFinish)
117 msg = "Task " + event.getTask().getTaskName() + " started";
118
119 slcExecution.getSteps().add(new SlcExecutionStep("LOG", msg));
120
121 currentStepNotified = false;
122 }
123
124 public void taskFinished(BuildEvent event) {
125 if (!shouldLog())
126 return;
127
128 SlcExecution slcExecution = getSlcExecution(event);
129 if (!currentStepNotified) {
130
131 if (logTaskStartFinish)
132 slcExecution.currentStep().addLog(
133 "Task " + event.getTask().getTaskName() + " finished");
134
135 notifyStep(slcExecution, slcExecution.currentStep());
136 currentStepNotified = true;
137 }
138 }
139
140 public void setNotifiers(List<SlcExecutionNotifier> notifiers) {
141 this.notifiers = notifiers;
142 }
143
144 protected SlcExecution getSlcExecution(BuildEvent event) {
145 Project projectEvt = event.getProject();
146 if (!projectEvt.equals(project))
147 throw new SlcAntException("Event project " + projectEvt
148 + " not consistent with listener project " + project);
149
150 SlcExecution slcExecution = (SlcExecution) project
151 .getReference(REF_SLC_EXECUTION);
152
153 if (slcExecution == null)
154 throw new SlcAntException("No SLC Execution registered.");
155 return slcExecution;
156 }
157
158 protected void addLogStep(BuildEvent event, String msg) {
159 SlcExecution slcExecution = getSlcExecution(event);
160 slcExecution.getSteps().add(new SlcExecutionStep("LOG", msg));
161
162 notifyStep(slcExecution, slcExecution.currentStep());
163 currentStepNotified = true;
164 }
165
166 protected void notifyStep(SlcExecution slcExecution, SlcExecutionStep step) {
167 Vector<SlcExecutionStep> additionalSteps = new Vector<SlcExecutionStep>();
168 additionalSteps.add(step);
169 notifySteps(slcExecution, additionalSteps);
170 }
171
172 protected void notifySteps(SlcExecution slcExecution,
173 List<SlcExecutionStep> additionalSteps) {
174 for (SlcExecutionNotifier notifier : notifiers) {
175 notifier.addSteps(slcExecution, additionalSteps);
176 }
177 }
178
179 /* Log4j methods */
180
181 @Override
182 protected void append(LoggingEvent event) {
183 if (isLogging) {
184 // avoid StackOverflow if notification calls Log4j itself.
185 return;
186 }
187
188 if (event.getLoggerName().equals(
189 WebServiceSlcExecutionNotifier.class.getName())) {
190 return;
191 }
192
193 isLogging = true;
194
195 try {
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()
202 .toString()));
203 currentStepNotified = false;
204 }
205 slcExecution.currentStep()
206 .addLog(event.getMessage().toString());
207 } else {
208 // TODO: log before initialization?
209 }
210 } finally {
211 isLogging = false;
212 }
213
214 }
215
216 protected boolean shouldLog() {
217 return logBeforeFirstTarget || firstTargetStarted;
218 }
219
220 @Override
221 public void close() {
222 }
223
224 @Override
225 public boolean requiresLayout() {
226 return false;
227 }
228
229 public Project getProject() {
230 return project;
231 }
232
233 }