2 * Copyright (C) 2007-2012 Mathieu Baudier
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.client
.ui
.editors
;
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
;
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
;
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
;
46 public class ProcessLogPage
extends FormPage
{
47 public final static String ID
= "processLogPage";
49 private DateFormat dateFormat
= new SimpleDateFormat("HH:mm:ss");
51 /** Where the log is displayed. */
54 * Stores logs received before the text was shown. TODO : rather store in in
55 * JCR and reads it from there.
57 private StringBuffer beforeTextInit
= new StringBuffer("");
59 private Node processNode
;
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.
64 //private Integer logPathLength;
66 public ProcessLogPage(FormEditor editor
, Node processNode
) {
67 super(editor
, ID
, "Log");
68 this.processNode
= processNode
;
70 EventListener listener
= new LogListener(editor
.getSite().getPage()
71 .getWorkbenchWindow().getWorkbench().getDisplay());
74 String logBasePath
= processNode
.getPath() + '/' + SlcNames
.SLC_LOG
;
75 //logPathLength = logBasePath.length();
77 Workspace ws
= processNode
.getSession().getWorkspace();
79 String statement
= "SELECT * FROM ["
80 + SlcTypes
.SLC_LOG_ENTRY
82 + " WHERE ISDESCENDANTNODE('"
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()
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
);
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
108 text
.setEditable(false);
110 // transfer the existing buffer the first time
111 if (beforeTextInit
.length() > 0) {
112 text
.append(beforeTextInit
.toString());
114 beforeTextInit
.setLength(0);
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);
128 // FormToolkit tk = getManagedForm().getToolkit();
129 // text = tk.createText(form.getBody(), "", SWT.MULTI | SWT.H_SCROLL
131 // text.setEditable(false);
132 // // transfer the existing buffer the first time
133 // if (beforeTextInit.length() > 0) {
134 // text.append(beforeTextInit.toString());
136 // beforeTextInit.setLength(0);
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);
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());
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()));
169 if (step
.getType().equals(ExecutionStep
.PHASE_START
)) {
170 buf
.append("## START ").append(step
.getLog());
172 } else if (step
.getType().equals(ExecutionStep
.PHASE_END
)) {
173 buf
.append("## END ").append(step
.getLog());
176 buf
.append(step
.getLog());
181 Display
.getDefault().asyncExec(new Runnable() {
183 text
.append(buf
.toString());
187 beforeTextInit
.append(buf
);
191 public Control
getPartControl() {
196 public void setFocus() {
201 /** JCR event listener notifying when new nodes are added */
202 private class LogListener
extends AsyncUiEventListener
{
204 public LogListener(Display display
) {
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
214 SortedMap
<Long
, Node
> nodes
= new TreeMap
<Long
, Node
>();
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
);
224 StringBuffer buf
= new StringBuffer("");
225 for (Node logEntry
: nodes
.values()) {
226 appendLogEntry(buf
, logEntry
);
230 text
.append(buf
.toString());
232 beforeTextInit
.append(buf
);