1 package org
.argeo
.slc
.client
.ui
.editors
;
3 import java
.text
.DateFormat
;
4 import java
.text
.SimpleDateFormat
;
6 import java
.util
.SortedMap
;
7 import java
.util
.TreeMap
;
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
;
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
;
31 public class ProcessLogPage
extends FormPage
{
32 public final static String ID
= "processLogPage";
34 private DateFormat dateFormat
= new SimpleDateFormat("HH:mm:ss");
36 /** Where the log is displayed. */
39 * Stores logs received before the text was shown. TODO : rather store in in
40 * JCR and reads it from there.
42 private StringBuffer beforeTextInit
= new StringBuffer("");
44 private Node processNode
;
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.
49 private Integer logPathLength
;
51 public ProcessLogPage(FormEditor editor
, Node processNode
) {
52 super(editor
, ID
, "Log");
53 this.processNode
= processNode
;
55 EventListener listener
= new LogListener(editor
.getSite().getPage()
56 .getWorkbenchWindow().getWorkbench().getDisplay());
59 String logBasePath
= processNode
.getPath() + '/' + SlcNames
.SLC_LOG
;
60 logPathLength
= logBasePath
.length();
62 Workspace ws
= processNode
.getSession().getWorkspace();
64 String statement
= "SELECT * FROM ["
65 + SlcTypes
.SLC_LOG_ENTRY
67 + " WHERE ISDESCENDANTNODE('"
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()
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
);
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
93 text
.setEditable(false);
95 // transfer the existing buffer the first time
96 if (beforeTextInit
.length() > 0) {
97 text
.append(beforeTextInit
.toString());
99 beforeTextInit
.setLength(0);
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);
113 // FormToolkit tk = getManagedForm().getToolkit();
114 // text = tk.createText(form.getBody(), "", SWT.MULTI | SWT.H_SCROLL
116 // text.setEditable(false);
117 // // transfer the existing buffer the first time
118 // if (beforeTextInit.length() > 0) {
119 // text.append(beforeTextInit.toString());
121 // beforeTextInit.setLength(0);
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
);
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());
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()));
154 if (step
.getType().equals(ExecutionStep
.PHASE_START
)) {
155 buf
.append("## START ").append(step
.getLog());
157 } else if (step
.getType().equals(ExecutionStep
.PHASE_END
)) {
158 buf
.append("## END ").append(step
.getLog());
161 buf
.append(step
.getLog());
166 Display
.getDefault().asyncExec(new Runnable() {
168 text
.append(buf
.toString());
172 beforeTextInit
.append(buf
);
176 public Control
getPartControl() {
181 public void setFocus() {
186 /** JCR event listener notifying when new nodes are added */
187 private class LogListener
extends AsyncUiEventListener
{
189 public LogListener(Display display
) {
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
199 SortedMap
<Long
, Node
> nodes
= new TreeMap
<Long
, Node
>();
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
);
209 StringBuffer buf
= new StringBuffer("");
210 for (Node logEntry
: nodes
.values()) {
211 appendLogEntry(buf
, logEntry
);
215 text
.append(buf
.toString());
217 beforeTextInit
.append(buf
);