View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
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.views;
17  
18  import java.text.DateFormat;
19  import java.text.SimpleDateFormat;
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import javax.jcr.Node;
24  import javax.jcr.NodeIterator;
25  import javax.jcr.Property;
26  import javax.jcr.Repository;
27  import javax.jcr.RepositoryException;
28  import javax.jcr.Session;
29  import javax.jcr.observation.Event;
30  import javax.jcr.observation.EventListener;
31  import javax.jcr.observation.ObservationManager;
32  import javax.jcr.query.Query;
33  
34  import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
35  import org.argeo.jcr.JcrUtils;
36  import org.argeo.slc.SlcException;
37  import org.argeo.slc.SlcNames;
38  import org.argeo.slc.SlcTypes;
39  import org.argeo.slc.client.ui.ClientUiPlugin;
40  import org.argeo.slc.client.ui.SlcImages;
41  import org.argeo.slc.client.ui.editors.ProcessEditor;
42  import org.argeo.slc.client.ui.editors.ProcessEditorInput;
43  import org.argeo.slc.execution.ExecutionProcess;
44  import org.argeo.slc.jcr.SlcJcrUtils;
45  import org.eclipse.jface.viewers.ColumnLabelProvider;
46  import org.eclipse.jface.viewers.DoubleClickEvent;
47  import org.eclipse.jface.viewers.IDoubleClickListener;
48  import org.eclipse.jface.viewers.IStructuredContentProvider;
49  import org.eclipse.jface.viewers.IStructuredSelection;
50  import org.eclipse.jface.viewers.ITableLabelProvider;
51  import org.eclipse.jface.viewers.TableViewer;
52  import org.eclipse.jface.viewers.Viewer;
53  import org.eclipse.rap.rwt.service.ServerPushSession;
54  import org.eclipse.swt.SWT;
55  import org.eclipse.swt.graphics.Image;
56  import org.eclipse.swt.widgets.Composite;
57  import org.eclipse.swt.widgets.Table;
58  import org.eclipse.swt.widgets.TableColumn;
59  import org.eclipse.ui.IWorkbenchPage;
60  import org.eclipse.ui.PlatformUI;
61  import org.eclipse.ui.part.ViewPart;
62  
63  /** Displays processes. */
64  public class JcrProcessListView extends ViewPart {
65  	public static final String ID = ClientUiPlugin.ID + ".jcrProcessListView";
66  
67  	private TableViewer viewer;
68  	private ServerPushSession pushSession;
69  
70  	private Repository repository;
71  	private Session session;
72  
73  	private EventListener processesObserver;
74  
75  	private DateFormat dateFormat = new SimpleDateFormat(
76  			"EEE, dd MMM yyyy HH:mm:ss");
77  	private Integer queryLimit = 2000;
78  
79  	public void createPartControl(Composite parent) {
80  		pushSession = new ServerPushSession();
81  		pushSession.start();
82  		try {
83  			session = repository.login();
84  		} catch (RepositoryException re) {
85  			throw new SlcException("Unable to log in Repository " + repository,
86  					re);
87  		}
88  		Table table = createTable(parent);
89  		viewer = new TableViewer(table);
90  		viewer.setLabelProvider(new LabelProvider());
91  		viewer.setContentProvider(new ContentProvider());
92  		viewer.setInput(getViewSite());
93  		viewer.addDoubleClickListener(new ViewDoubleClickListener());
94  
95  		processesObserver = new AsyncUiEventListener(viewer.getTable()
96  				.getDisplay()) {
97  			protected void onEventInUiThread(List<Event> events) {
98  				// TODO optimize by updating only the changed process
99  				viewer.refresh();
100 			}
101 		};
102 		try {
103 			ObservationManager observationManager = session.getWorkspace()
104 					.getObservationManager();
105 			observationManager.addEventListener(processesObserver,
106 					Event.NODE_ADDED | Event.NODE_REMOVED
107 							| Event.PROPERTY_CHANGED,
108 					SlcJcrUtils.getSlcProcessesBasePath(session), true, null,
109 					null, false);
110 		} catch (RepositoryException e) {
111 			throw new SlcException("Cannot register listeners", e);
112 		}
113 
114 	}
115 
116 	protected Table createTable(Composite parent) {
117 		int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL
118 				| SWT.FULL_SELECTION;
119 		// does not function with RAP, commented for the time being
120 		// | SWT.HIDE_SELECTION;
121 
122 		Table table = new Table(parent, style);
123 
124 		table.setLinesVisible(true);
125 		table.setHeaderVisible(true);
126 
127 		TableColumn column = new TableColumn(table, SWT.LEFT, 0);
128 		column.setText("Date");
129 		column.setWidth(200);
130 
131 		column = new TableColumn(table, SWT.LEFT, 1);
132 		column.setText("Host");
133 		column.setWidth(100);
134 
135 		column = new TableColumn(table, SWT.LEFT, 2);
136 		column.setText("Id");
137 		column.setWidth(300);
138 
139 		column = new TableColumn(table, SWT.LEFT, 3);
140 		column.setText("Status");
141 		column.setWidth(100);
142 
143 		return table;
144 	}
145 
146 	public void setFocus() {
147 		viewer.getControl().setFocus();
148 	}
149 
150 	class ContentProvider implements IStructuredContentProvider {
151 
152 		public Object[] getElements(Object inputElement) {
153 			try {
154 				// TODO filter, optimize with virtual table, ...
155 				String sql = "SELECT * from [slc:process] ORDER BY [jcr:lastModified] DESC";
156 				Query query = session.getWorkspace().getQueryManager()
157 						.createQuery(sql, Query.JCR_SQL2);
158 				// TODO paging
159 				query.setLimit(queryLimit);
160 				List<Node> nodes = new ArrayList<Node>();
161 				for (NodeIterator nit = query.execute().getNodes(); nit
162 						.hasNext();) {
163 					nodes.add(nit.nextNode());
164 				}
165 				return nodes.toArray();
166 			} catch (RepositoryException e) {
167 				throw new SlcException("Cannot retrieve processes", e);
168 			}
169 		}
170 
171 		public void dispose() {
172 		}
173 
174 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
175 		}
176 
177 	}
178 
179 	class LabelProvider extends ColumnLabelProvider implements
180 			ITableLabelProvider {
181 
182 		public Image getColumnImage(Object obj, int columnIndex) {
183 			if (columnIndex != 0)
184 				return null;
185 			try {
186 				Node node = (Node) obj;
187 				String status = node.getProperty(SlcNames.SLC_STATUS)
188 						.getString();
189 				if (status.equals(ExecutionProcess.NEW)
190 						|| status.equals(ExecutionProcess.INITIALIZED)
191 						|| status.equals(ExecutionProcess.SCHEDULED))
192 					return SlcImages.PROCESS_SCHEDULED;
193 				else if (status.equals(ExecutionProcess.ERROR)
194 						|| status.equals(ExecutionProcess.UNKOWN))
195 					return SlcImages.PROCESS_ERROR;
196 				else if (status.equals(ExecutionProcess.COMPLETED))
197 					return SlcImages.PROCESS_COMPLETED;
198 				else if (status.equals(ExecutionProcess.RUNNING))
199 					return SlcImages.PROCESS_RUNNING;
200 				else if (status.equals(ExecutionProcess.KILLED))
201 					return SlcImages.PROCESS_ERROR;
202 				else
203 					throw new SlcException("Unkown status " + status);
204 			} catch (RepositoryException e) {
205 				throw new SlcException("Cannot get column text", e);
206 			}
207 		}
208 
209 		public String getColumnText(Object obj, int index) {
210 			try {
211 				Node node = (Node) obj;
212 				switch (index) {
213 
214 				case 0:
215 					return dateFormat.format(node
216 							.getProperty(Property.JCR_LAST_MODIFIED).getDate()
217 							.getTime());
218 				case 1:
219 					return "local";
220 				case 2:
221 					return node.getProperty(SlcNames.SLC_UUID).getString();
222 				case 3:
223 					return node.getProperty(SlcNames.SLC_STATUS).getString();
224 				}
225 				return getText(obj);
226 			} catch (RepositoryException e) {
227 				throw new SlcException("Cannot get column text", e);
228 			}
229 		}
230 
231 	}
232 
233 	class ViewDoubleClickListener implements IDoubleClickListener {
234 		public void doubleClick(DoubleClickEvent evt) {
235 			Object obj = ((IStructuredSelection) evt.getSelection())
236 					.getFirstElement();
237 			try {
238 				if (obj instanceof Node) {
239 					Node node = (Node) obj;
240 					if (node.isNodeType(SlcTypes.SLC_PROCESS)) {
241 						IWorkbenchPage activePage = PlatformUI.getWorkbench()
242 								.getActiveWorkbenchWindow().getActivePage();
243 						activePage.openEditor(
244 								new ProcessEditorInput(node.getPath()),
245 								ProcessEditor.ID);
246 					}
247 				}
248 			} catch (Exception e) {
249 				throw new SlcException("Cannot open " + obj, e);
250 			}
251 		}
252 
253 	}
254 
255 	public void dispose() {
256 		JcrUtils.unregisterQuietly(session.getWorkspace(), processesObserver);
257 		JcrUtils.logoutQuietly(session);
258 		if (pushSession != null)
259 			pushSession.stop();
260 		super.dispose();
261 	}
262 
263 	public void setRepository(Repository repository) {
264 		this.repository = repository;
265 	}
266 
267 }