]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java
Restructure deployment
[gpl/argeo-slc.git] / org.argeo.slc.agent / 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 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
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";
20
21 public static final String REF_SLC_EXECUTION = "slcExecution";
22
23 private Project project;
24
25 // to avoid stack overflow when logging for log4j
26 private boolean isLogging = false;
27
28 private List<SlcExecutionNotifier> notifiers = new Vector<SlcExecutionNotifier>();
29
30 private boolean currentStepNotified = true;
31
32 // CUSTOMIZATIONS
33 private boolean logBeforeFirstTarget = false;
34 private boolean firstTargetStarted = false;
35
36 private boolean logTaskStartFinish = true;
37
38 public void init(Project project) {
39 if (this.project != null) {
40 throw new SlcAntException("Build listener already initialized");
41 }
42
43 this.project = project;
44
45 if (!LogManager.getRootLogger().isAttached(this)) {
46 LogManager.getRootLogger().addAppender(this);
47 }
48
49 SlcExecution slcExecution = (SlcExecution) project
50 .getReference(REF_SLC_EXECUTION);
51 if (slcExecution == null)
52 throw new SlcAntException("No SLC Execution registered.");
53
54 for (SlcExecutionNotifier notifier : notifiers) {
55 notifier.newExecution(slcExecution);
56 }
57
58 }
59
60 public void buildStarted(BuildEvent event) {
61 }
62
63 public void buildFinished(BuildEvent event) {
64 SlcExecution slcExecution = getSlcExecution(event);
65 String oldStatus = slcExecution.getStatus();
66 slcExecution.setStatus(SlcExecution.STATUS_FINISHED);
67
68 for (SlcExecutionNotifier notifier : notifiers) {
69 notifier.updateStatus(slcExecution, oldStatus, slcExecution
70 .getStatus());
71 }
72 }
73
74 public void messageLogged(BuildEvent event) {
75 if (!shouldLog())
76 return;
77
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;
85 } else {
86 slcExecution.currentStep().addLog(event.getMessage());
87 }
88 } else {
89 // TODO: log before initialization?
90 }
91 }
92
93 public void targetStarted(BuildEvent event) {
94 if (!firstTargetStarted)
95 firstTargetStarted = true;
96
97 addLogStep(event, "Target " + event.getTarget().getName() + " started");
98 }
99
100 public void targetFinished(BuildEvent event) {
101 addLogStep(event, "Target " + event.getTarget().getName() + " finished");
102 }
103
104 public void taskStarted(BuildEvent event) {
105 if (!shouldLog())
106 return;
107
108 SlcExecution slcExecution = getSlcExecution(event);
109 if (!currentStepNotified) {
110 notifyStep(slcExecution, slcExecution.currentStep());
111 currentStepNotified = true;
112 }
113
114 String msg = null;
115 if (logTaskStartFinish)
116 msg = "Task " + event.getTask().getTaskName() + " started";
117
118 slcExecution.getSteps().add(new SlcExecutionStep("LOG", msg));
119
120 currentStepNotified = false;
121 }
122
123 public void taskFinished(BuildEvent event) {
124 if (!shouldLog())
125 return;
126
127 SlcExecution slcExecution = getSlcExecution(event);
128 if (!currentStepNotified) {
129
130 if (logTaskStartFinish)
131 slcExecution.currentStep().addLog(
132 "Task " + event.getTask().getTaskName() + " finished");
133
134 notifyStep(slcExecution, slcExecution.currentStep());
135 currentStepNotified = true;
136 }
137 }
138
139 public void setNotifiers(List<SlcExecutionNotifier> notifiers) {
140 this.notifiers = notifiers;
141 }
142
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);
148
149 SlcExecution slcExecution = (SlcExecution) project
150 .getReference(REF_SLC_EXECUTION);
151
152 if (slcExecution == null)
153 throw new SlcAntException("No SLC Execution registered.");
154 return slcExecution;
155 }
156
157 protected void addLogStep(BuildEvent event, String msg) {
158 SlcExecution slcExecution = getSlcExecution(event);
159 slcExecution.getSteps().add(new SlcExecutionStep("LOG", msg));
160
161 notifyStep(slcExecution, slcExecution.currentStep());
162 currentStepNotified = true;
163 }
164
165 protected void notifyStep(SlcExecution slcExecution, SlcExecutionStep step) {
166 Vector<SlcExecutionStep> additionalSteps = new Vector<SlcExecutionStep>();
167 additionalSteps.add(step);
168 notifySteps(slcExecution, additionalSteps);
169 }
170
171 protected void notifySteps(SlcExecution slcExecution,
172 List<SlcExecutionStep> additionalSteps) {
173 for (SlcExecutionNotifier notifier : notifiers) {
174 notifier.addSteps(slcExecution, additionalSteps);
175 }
176 }
177
178 /* Log4j methods */
179
180 @Override
181 protected void append(LoggingEvent event) {
182 if (isLogging) {
183 // avoid StackOverflow if notification calls Log4j itself.
184 return;
185 }
186
187 // FIXME: make it more generic
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 }