1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.argeo.slc.client.ui.editors;
17
18 import java.text.DateFormat;
19 import java.text.SimpleDateFormat;
20 import java.util.List;
21 import java.util.SortedMap;
22 import java.util.TreeMap;
23
24 import javax.jcr.Node;
25 import javax.jcr.NodeIterator;
26 import javax.jcr.RepositoryException;
27 import javax.jcr.Workspace;
28 import javax.jcr.observation.Event;
29 import javax.jcr.observation.EventListener;
30 import javax.jcr.query.Query;
31
32 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
33 import org.argeo.slc.SlcException;
34 import org.argeo.slc.SlcNames;
35 import org.argeo.slc.SlcTypes;
36 import org.argeo.slc.execution.ExecutionStep;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Control;
40 import org.eclipse.swt.widgets.Display;
41 import org.eclipse.swt.widgets.Text;
42 import org.eclipse.ui.forms.editor.FormEditor;
43 import org.eclipse.ui.forms.editor.FormPage;
44 import org.eclipse.ui.forms.widgets.FormToolkit;
45
46 public class ProcessLogPage extends FormPage {
47 public final static String ID = "processLogPage";
48
49 private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
50
51
52 private Text text;
53
54
55
56
57 private StringBuffer beforeTextInit = new StringBuffer("");
58
59 private Node processNode;
60
61
62
63
64
65
66 public ProcessLogPage(FormEditor editor, Node processNode) {
67 super(editor, ID, "Log");
68 this.processNode = processNode;
69
70 EventListener listener = new LogListener(editor.getSite().getPage()
71 .getWorkbenchWindow().getWorkbench().getDisplay());
72
73 try {
74 String logBasePath = processNode.getPath() + '/' + SlcNames.SLC_LOG;
75
76
77 Workspace ws = processNode.getSession().getWorkspace();
78
79 String statement = "SELECT * FROM ["
80 + SlcTypes.SLC_LOG_ENTRY
81 + "] as logEntry"
82 + " WHERE ISDESCENDANTNODE('"
83 + logBasePath
84 + "')"
85 + " ORDER BY logEntry.[slc:timestamp] ASC, NAME(logEntry) ASC";
86 StringBuffer buf = new StringBuffer("");
87 NodeIterator it = ws.getQueryManager()
88 .createQuery(statement, Query.JCR_SQL2).execute()
89 .getNodes();
90 while (it.hasNext())
91 appendLogEntry(buf, it.nextNode());
92 beforeTextInit = new StringBuffer(buf.toString());
93
94 ws.getObservationManager().addEventListener(listener,
95 Event.NODE_ADDED, logBasePath, true, null, null, false);
96 } catch (RepositoryException e) {
97 throw new SlcException("Cannot register listener", e);
98 }
99 }
100
101 @Override
102 public synchronized void createPartControl(Composite parent) {
103
104 FormToolkit tk = getEditor().getToolkit();
105
106 text = tk.createText(parent, "", SWT.MULTI | SWT.H_SCROLL
107 | SWT.V_SCROLL);
108 text.setEditable(false);
109
110
111 if (beforeTextInit.length() > 0) {
112 text.append(beforeTextInit.toString());
113
114 beforeTextInit.setLength(0);
115 }
116
117 }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 protected void appendLogEntry(StringBuffer buf, Node logEntry)
141 throws RepositoryException {
142
143
144
145
146
147
148
149
150
151
152 String date = logEntry.getProperty(SlcNames.SLC_TIMESTAMP).getString();
153 buf.append(date).append(' ');
154 String type = logEntry.getPrimaryNodeType().getName().substring(7);
155 buf.append(type).append('\t');
156
157
158 buf.append(logEntry.getProperty(SlcNames.SLC_MESSAGE).getString());
159 buf.append('\n');
160
161 }
162
163
164 public synchronized void addSteps(List<ExecutionStep> steps) {
165 final StringBuffer buf = new StringBuffer("");
166 for (ExecutionStep step : steps) {
167 buf.append(dateFormat.format(step.getTimestamp()));
168 buf.append(' ');
169 if (step.getType().equals(ExecutionStep.PHASE_START)) {
170 buf.append("## START ").append(step.getLog());
171 buf.append('\n');
172 } else if (step.getType().equals(ExecutionStep.PHASE_END)) {
173 buf.append("## END ").append(step.getLog());
174 buf.append("\n");
175 } else {
176 buf.append(step.getLog());
177 }
178 }
179
180 if (text != null) {
181 Display.getDefault().asyncExec(new Runnable() {
182 public void run() {
183 text.append(buf.toString());
184 }
185 });
186 } else
187 beforeTextInit.append(buf);
188 }
189
190 @Override
191 public Control getPartControl() {
192 return text;
193 }
194
195 @Override
196 public void setFocus() {
197 if (text != null)
198 text.setFocus();
199 }
200
201
202 private class LogListener extends AsyncUiEventListener {
203
204 public LogListener(Display display) {
205 super(display);
206 }
207
208 @Override
209 protected void onEventInUiThread(List<Event> events)
210 throws RepositoryException {
211
212
213
214 SortedMap<Long, Node> nodes = new TreeMap<Long, Node>();
215
216 for (Event evt : events) {
217 Node newNode = ProcessLogPage.this.processNode.getSession()
218 .getNode(evt.getPath());
219 if (newNode.isNodeType(SlcTypes.SLC_LOG_ENTRY)) {
220 nodes.put(Long.parseLong(newNode.getName()), newNode);
221 }
222 }
223
224 StringBuffer buf = new StringBuffer("");
225 for (Node logEntry : nodes.values()) {
226 appendLogEntry(buf, logEntry);
227 }
228
229 if (text != null)
230 text.append(buf.toString());
231 else
232 beforeTextInit.append(buf);
233 }
234 }
235 }