]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessLogPage.java
Restructure SLC
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / editors / ProcessLogPage.java
1 /*
2 * Copyright (C) 2007-2012 Mathieu Baudier
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
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.execution.ExecutionStep;
35 import org.argeo.slc.jcr.SlcNames;
36 import org.argeo.slc.jcr.SlcTypes;
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 /** Where the log is displayed. */
52 private Text text;
53 /**
54 * Stores logs received before the text was shown. TODO : rather store in in
55 * JCR and reads it from there.
56 */
57 private StringBuffer beforeTextInit = new StringBuffer("");
58
59 private Node processNode;
60 /**
61 * optimization field: we compute once the length of the path to slc:log so
62 * that we can easily substring the relative path of logs.
63 */
64 //private Integer logPathLength;
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 //logPathLength = logBasePath.length();
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 // text.setText(buf.toString());
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 // bypass createFormContent
104 FormToolkit tk = getEditor().getToolkit();
105 // parent.setLayout(new FillLayout());
106 text = tk.createText(parent, "", SWT.MULTI | SWT.H_SCROLL
107 | SWT.V_SCROLL);
108 text.setEditable(false);
109
110 // transfer the existing buffer the first time
111 if (beforeTextInit.length() > 0) {
112 text.append(beforeTextInit.toString());
113 // clear buffer
114 beforeTextInit.setLength(0);
115 }
116
117 }
118
119 // @Override
120 // protected synchronized void createFormContent(IManagedForm mf) {
121 // ScrolledForm form = mf.getForm();
122 // form.setExpandHorizontal(true);
123 // form.setExpandVertical(true);
124 // // form.setText("Log");
125 // FillLayout mainLayout = new FillLayout();
126 // form.getBody().setLayout(mainLayout);
127 //
128 // FormToolkit tk = getManagedForm().getToolkit();
129 // text = tk.createText(form.getBody(), "", SWT.MULTI | SWT.H_SCROLL
130 // | SWT.V_SCROLL);
131 // text.setEditable(false);
132 // // transfer the existing buffer the first time
133 // if (beforeTextInit.length() > 0) {
134 // text.append(beforeTextInit.toString());
135 // // clear buffer
136 // beforeTextInit.setLength(0);
137 // }
138 // }
139
140 protected void appendLogEntry(StringBuffer buf, Node logEntry)
141 throws RepositoryException {
142 // +1 in order to remove the first slash
143 // String relPath = logEntry.getPath().substring(logPathLength + 1);
144 //System.out.println("relPath=" + relPath);
145 // int firstSlashIndex = relPath.indexOf('/');
146 // int lastSlashIndex = relPath.lastIndexOf('/');
147 // String thread = relPath.substring(0, firstSlashIndex);
148 // String location = relPath.substring(firstSlashIndex, lastSlashIndex);
149
150 // String date = dateFormat.format(logEntry
151 // .getProperty(SlcNames.SLC_TIMESTAMP).getDate().getTime());
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 // buf.append(thread).append('\t');
157 // buf.append(location).append('\t');
158 buf.append(logEntry.getProperty(SlcNames.SLC_MESSAGE).getString());
159 buf.append('\n');
160
161 }
162
163 /** @deprecated */
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 /** JCR event listener notifying when new nodes are added */
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 // since we use batch save, order is not guaranteed
212 // so we need to reorder, according to log line number for the time
213 // being
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 }