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 }