]> git.argeo.org Git - gpl/argeo-slc.git/blob - eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessLogPage.java
Re-enable tooltip support (works only on RCP so far)
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / editors / ProcessLogPage.java
1 package org.argeo.slc.client.ui.editors;
2
3 import java.text.DateFormat;
4 import java.text.SimpleDateFormat;
5 import java.util.List;
6 import java.util.SortedMap;
7 import java.util.TreeMap;
8
9 import javax.jcr.Node;
10 import javax.jcr.NodeIterator;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.Workspace;
13 import javax.jcr.observation.Event;
14 import javax.jcr.observation.EventListener;
15 import javax.jcr.query.Query;
16
17 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
18 import org.argeo.slc.SlcException;
19 import org.argeo.slc.execution.ExecutionStep;
20 import org.argeo.slc.jcr.SlcNames;
21 import org.argeo.slc.jcr.SlcTypes;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.swt.widgets.Control;
25 import org.eclipse.swt.widgets.Display;
26 import org.eclipse.swt.widgets.Text;
27 import org.eclipse.ui.forms.editor.FormEditor;
28 import org.eclipse.ui.forms.editor.FormPage;
29 import org.eclipse.ui.forms.widgets.FormToolkit;
30
31 public class ProcessLogPage extends FormPage {
32 public final static String ID = "processLogPage";
33
34 private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
35
36 /** Where the log is displayed. */
37 private Text text;
38 /**
39 * Stores logs received before the text was shown. TODO : rather store in in
40 * JCR and reads it from there.
41 */
42 private StringBuffer beforeTextInit = new StringBuffer("");
43
44 private Node processNode;
45 /**
46 * optimization field: we compute once the length of the path to slc:log so
47 * that we can easily substring the relative path of logs.
48 */
49 private Integer logPathLength;
50
51 public ProcessLogPage(FormEditor editor, Node processNode) {
52 super(editor, ID, "Log");
53 this.processNode = processNode;
54
55 EventListener listener = new LogListener(editor.getSite().getPage()
56 .getWorkbenchWindow().getWorkbench().getDisplay());
57
58 try {
59 String logBasePath = processNode.getPath() + '/' + SlcNames.SLC_LOG;
60 logPathLength = logBasePath.length();
61
62 Workspace ws = processNode.getSession().getWorkspace();
63
64 String statement = "SELECT * FROM ["
65 + SlcTypes.SLC_LOG_ENTRY
66 + "] as logEntry"
67 + " WHERE ISDESCENDANTNODE('"
68 + logBasePath
69 + "')"
70 + " ORDER BY logEntry.[slc:timestamp] ASC, NAME(logEntry) ASC";
71 StringBuffer buf = new StringBuffer("");
72 NodeIterator it = ws.getQueryManager()
73 .createQuery(statement, Query.JCR_SQL2).execute()
74 .getNodes();
75 while (it.hasNext())
76 appendLogEntry(buf, it.nextNode());
77 beforeTextInit = new StringBuffer(buf.toString());
78 // text.setText(buf.toString());
79 ws.getObservationManager().addEventListener(listener,
80 Event.NODE_ADDED, logBasePath, true, null, null, false);
81 } catch (RepositoryException e) {
82 throw new SlcException("Cannot register listener", e);
83 }
84 }
85
86 @Override
87 public synchronized void createPartControl(Composite parent) {
88 // bypass createFormContent
89 FormToolkit tk = getEditor().getToolkit();
90 // parent.setLayout(new FillLayout());
91 text = tk.createText(parent, "", SWT.MULTI | SWT.H_SCROLL
92 | SWT.V_SCROLL);
93 text.setEditable(false);
94
95 // transfer the existing buffer the first time
96 if (beforeTextInit.length() > 0) {
97 text.append(beforeTextInit.toString());
98 // clear buffer
99 beforeTextInit.setLength(0);
100 }
101
102 }
103
104 // @Override
105 // protected synchronized void createFormContent(IManagedForm mf) {
106 // ScrolledForm form = mf.getForm();
107 // form.setExpandHorizontal(true);
108 // form.setExpandVertical(true);
109 // // form.setText("Log");
110 // FillLayout mainLayout = new FillLayout();
111 // form.getBody().setLayout(mainLayout);
112 //
113 // FormToolkit tk = getManagedForm().getToolkit();
114 // text = tk.createText(form.getBody(), "", SWT.MULTI | SWT.H_SCROLL
115 // | SWT.V_SCROLL);
116 // text.setEditable(false);
117 // // transfer the existing buffer the first time
118 // if (beforeTextInit.length() > 0) {
119 // text.append(beforeTextInit.toString());
120 // // clear buffer
121 // beforeTextInit.setLength(0);
122 // }
123 // }
124
125 protected void appendLogEntry(StringBuffer buf, Node logEntry)
126 throws RepositoryException {
127 // +1 in order to remove the first slash
128 String relPath = logEntry.getPath().substring(logPathLength + 1);
129 //System.out.println("relPath=" + relPath);
130 int firstSlashIndex = relPath.indexOf('/');
131 int lastSlashIndex = relPath.lastIndexOf('/');
132 String thread = relPath.substring(0, firstSlashIndex);
133 String location = relPath.substring(firstSlashIndex, lastSlashIndex);
134
135 // String date = dateFormat.format(logEntry
136 // .getProperty(SlcNames.SLC_TIMESTAMP).getDate().getTime());
137 String date = logEntry.getProperty(SlcNames.SLC_TIMESTAMP).getString();
138 buf.append(date).append(' ');
139 String type = logEntry.getPrimaryNodeType().getName().substring(7);
140 buf.append(type).append('\t');
141 // buf.append(thread).append('\t');
142 // buf.append(location).append('\t');
143 buf.append(logEntry.getProperty(SlcNames.SLC_MESSAGE).getString());
144 buf.append('\n');
145
146 }
147
148 /** @deprecated */
149 public synchronized void addSteps(List<ExecutionStep> steps) {
150 final StringBuffer buf = new StringBuffer("");
151 for (ExecutionStep step : steps) {
152 buf.append(dateFormat.format(step.getTimestamp()));
153 buf.append(' ');
154 if (step.getType().equals(ExecutionStep.PHASE_START)) {
155 buf.append("## START ").append(step.getLog());
156 buf.append('\n');
157 } else if (step.getType().equals(ExecutionStep.PHASE_END)) {
158 buf.append("## END ").append(step.getLog());
159 buf.append("\n");
160 } else {
161 buf.append(step.getLog());
162 }
163 }
164
165 if (text != null) {
166 Display.getDefault().asyncExec(new Runnable() {
167 public void run() {
168 text.append(buf.toString());
169 }
170 });
171 } else
172 beforeTextInit.append(buf);
173 }
174
175 @Override
176 public Control getPartControl() {
177 return text;
178 }
179
180 @Override
181 public void setFocus() {
182 if (text != null)
183 text.setFocus();
184 }
185
186 /** JCR event listener notifying when new nodes are added */
187 private class LogListener extends AsyncUiEventListener {
188
189 public LogListener(Display display) {
190 super(display);
191 }
192
193 @Override
194 protected void onEventInUiThread(List<Event> events)
195 throws RepositoryException {
196 // since we use batch save, order is not guaranteed
197 // so we need to reorder, according to log line number for the time
198 // being
199 SortedMap<Long, Node> nodes = new TreeMap<Long, Node>();
200
201 for (Event evt : events) {
202 Node newNode = ProcessLogPage.this.processNode.getSession()
203 .getNode(evt.getPath());
204 if (newNode.isNodeType(SlcTypes.SLC_LOG_ENTRY)) {
205 nodes.put(Long.parseLong(newNode.getName()), newNode);
206 }
207 }
208
209 StringBuffer buf = new StringBuffer("");
210 for (Node logEntry : nodes.values()) {
211 appendLogEntry(buf, logEntry);
212 }
213
214 if (text != null)
215 text.append(buf.toString());
216 else
217 beforeTextInit.append(buf);
218 }
219 }
220 }