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