]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java
Improve digest utilities
[lgpl/argeo-commons.git] / org.argeo.cms.ui.workbench / src / org / argeo / cms / ui / workbench / internal / jcr / parts / AbstractJcrQueryEditor.java
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.cms.ui.workbench.internal.jcr.parts;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import javax.jcr.RepositoryException;
22 import javax.jcr.Session;
23 import javax.jcr.query.QueryResult;
24 import javax.jcr.query.Row;
25 import javax.jcr.query.RowIterator;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.argeo.eclipse.ui.EclipseUiException;
30 import org.argeo.eclipse.ui.GenericTableComparator;
31 import org.eclipse.core.runtime.IProgressMonitor;
32 import org.eclipse.core.runtime.IStatus;
33 import org.eclipse.core.runtime.Status;
34 import org.eclipse.jface.dialogs.ErrorDialog;
35 import org.eclipse.jface.viewers.ColumnLabelProvider;
36 import org.eclipse.jface.viewers.IDoubleClickListener;
37 import org.eclipse.jface.viewers.IStructuredContentProvider;
38 import org.eclipse.jface.viewers.TableViewer;
39 import org.eclipse.jface.viewers.TableViewerColumn;
40 import org.eclipse.jface.viewers.Viewer;
41 import org.eclipse.swt.SWT;
42 import org.eclipse.swt.custom.SashForm;
43 import org.eclipse.swt.events.SelectionAdapter;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.graphics.Image;
46 import org.eclipse.swt.layout.FillLayout;
47 import org.eclipse.swt.layout.GridData;
48 import org.eclipse.swt.layout.GridLayout;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.TableColumn;
51 import org.eclipse.ui.IEditorInput;
52 import org.eclipse.ui.IEditorSite;
53 import org.eclipse.ui.PartInitException;
54 import org.eclipse.ui.part.EditorPart;
55
56 /** Executes any JCR query. */
57 public abstract class AbstractJcrQueryEditor extends EditorPart {
58 private final static Log log = LogFactory.getLog(AbstractJcrQueryEditor.class);
59
60 protected String initialQuery;
61 protected String initialQueryType;
62
63 /* DEPENDENCY INJECTION */
64 private Session session;
65
66 // Widgets
67 private TableViewer viewer;
68 private List<TableViewerColumn> tableViewerColumns = new ArrayList<TableViewerColumn>();
69 private GenericTableComparator comparator;
70
71 /** Override to layout a form enabling the end user to build his query */
72 protected abstract void createQueryForm(Composite parent);
73
74 @Override
75 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
76 JcrQueryEditorInput editorInput = (JcrQueryEditorInput) input;
77 initialQuery = editorInput.getQuery();
78 initialQueryType = editorInput.getQueryType();
79 setSite(site);
80 setInput(editorInput);
81 }
82
83 @Override
84 public final void createPartControl(final Composite parent) {
85 parent.setLayout(new FillLayout());
86
87 SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
88 sashForm.setSashWidth(4);
89 sashForm.setLayout(new FillLayout());
90
91 Composite top = new Composite(sashForm, SWT.NONE);
92 GridLayout gl = new GridLayout(1, false);
93 top.setLayout(gl);
94
95 createQueryForm(top);
96
97 Composite bottom = new Composite(sashForm, SWT.NONE);
98 bottom.setLayout(new GridLayout(1, false));
99 sashForm.setWeights(getWeights());
100
101 viewer = new TableViewer(bottom);
102 viewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
103 viewer.getTable().setHeaderVisible(true);
104 viewer.setContentProvider(getQueryResultContentProvider());
105 viewer.setInput(getEditorSite());
106
107 if (getComparator() != null) {
108 comparator = getComparator();
109 viewer.setComparator(comparator);
110 }
111 if (getTableDoubleClickListener() != null)
112 viewer.addDoubleClickListener(getTableDoubleClickListener());
113
114 }
115
116 protected void executeQuery(String statement) {
117 try {
118 if (log.isDebugEnabled())
119 log.debug("Query : " + statement);
120
121 QueryResult qr = session.getWorkspace().getQueryManager().createQuery(statement, initialQueryType)
122 .execute();
123
124 // remove previous columns
125 for (TableViewerColumn tvc : tableViewerColumns)
126 tvc.getColumn().dispose();
127
128 int i = 0;
129 for (final String columnName : qr.getColumnNames()) {
130 TableViewerColumn tvc = new TableViewerColumn(viewer, SWT.NONE);
131 configureColumn(columnName, tvc, i);
132 tvc.setLabelProvider(getLabelProvider(columnName));
133 tableViewerColumns.add(tvc);
134 i++;
135 }
136
137 // Must create a local list: QueryResults can only be read once.
138 try {
139 List<Row> rows = new ArrayList<Row>();
140 RowIterator rit = qr.getRows();
141 while (rit.hasNext()) {
142 rows.add(rit.nextRow());
143 }
144 viewer.setInput(rows);
145 } catch (RepositoryException e) {
146 throw new EclipseUiException("Cannot read query result", e);
147 }
148
149 } catch (RepositoryException e) {
150 ErrorDialog.openError(null, "Error", "Cannot execute JCR query: " + statement,
151 new Status(IStatus.ERROR, "org.argeo.eclipse.ui.jcr", e.getMessage()));
152 }
153 }
154
155 /**
156 * To be overidden to adapt size of form and result frames.
157 *
158 * @return
159 */
160 protected int[] getWeights() {
161 return new int[] { 30, 70 };
162 }
163
164 /**
165 * To be overidden to implement a doubleclick Listener on one of the rows of
166 * the table.
167 *
168 * @return
169 */
170 protected IDoubleClickListener getTableDoubleClickListener() {
171 return null;
172 }
173
174 /**
175 * To be overiden in order to implement a specific
176 * QueryResultContentProvider
177 */
178 protected IStructuredContentProvider getQueryResultContentProvider() {
179 return new QueryResultContentProvider();
180 }
181
182 /**
183 * Enable specific implementation for columns
184 */
185 protected List<TableViewerColumn> getTableViewerColumns() {
186 return tableViewerColumns;
187 }
188
189 /**
190 * Enable specific implementation for columns
191 */
192 protected TableViewer getTableViewer() {
193 return viewer;
194 }
195
196 /**
197 * To be overridden in order to configure column label providers .
198 */
199 protected ColumnLabelProvider getLabelProvider(final String columnName) {
200 return new ColumnLabelProvider() {
201 private static final long serialVersionUID = -3539689333250152606L;
202
203 public String getText(Object element) {
204 Row row = (Row) element;
205 try {
206 return row.getValue(columnName).getString();
207 } catch (RepositoryException e) {
208 throw new EclipseUiException("Cannot display row " + row, e);
209 }
210 }
211
212 public Image getImage(Object element) {
213 return null;
214 }
215 };
216 }
217
218 /**
219 * To be overridden in order to configure the columns.
220 *
221 * @deprecated use
222 * {@link AbstractJcrQueryEditor#configureColumn(String, TableViewerColumn , int )}
223 * instead
224 */
225 protected void configureColumn(String jcrColumnName, TableViewerColumn column) {
226 column.getColumn().setWidth(50);
227 column.getColumn().setText(jcrColumnName);
228 }
229
230 /** To be overridden in order to configure the columns. */
231 protected void configureColumn(String jcrColumnName, TableViewerColumn column, int columnIndex) {
232 column.getColumn().setWidth(50);
233 column.getColumn().setText(jcrColumnName);
234 }
235
236 private class QueryResultContentProvider implements IStructuredContentProvider {
237 private static final long serialVersionUID = -5421095459600554741L;
238
239 public void dispose() {
240 }
241
242 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
243 }
244
245 public Object[] getElements(Object inputElement) {
246
247 if (inputElement instanceof List)
248 return ((List<?>) inputElement).toArray();
249
250 // Never reached might be deleted in future release
251 if (!(inputElement instanceof QueryResult))
252 return new String[] {};
253
254 try {
255 QueryResult queryResult = (QueryResult) inputElement;
256 List<Row> rows = new ArrayList<Row>();
257 RowIterator rit = queryResult.getRows();
258 while (rit.hasNext()) {
259 rows.add(rit.nextRow());
260 }
261
262 // List<Node> elems = new ArrayList<Node>();
263 // NodeIterator nit = queryResult.getNodes();
264 // while (nit.hasNext()) {
265 // elems.add(nit.nextNode());
266 // }
267 return rows.toArray();
268 } catch (RepositoryException e) {
269 throw new EclipseUiException("Cannot read query result", e);
270 }
271 }
272
273 }
274
275 /**
276 * Might be used by children classes to sort columns.
277 *
278 * @param column
279 * @param index
280 * @return
281 */
282 protected SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) {
283
284 // A comparator must be define
285 if (comparator == null)
286 return null;
287
288 SelectionAdapter selectionAdapter = new SelectionAdapter() {
289 private static final long serialVersionUID = 239829307927778349L;
290
291 @Override
292 public void widgetSelected(SelectionEvent e) {
293
294 try {
295
296 comparator.setColumn(index);
297 int dir = viewer.getTable().getSortDirection();
298 if (viewer.getTable().getSortColumn() == column) {
299 dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
300 } else {
301
302 dir = SWT.DOWN;
303 }
304 viewer.getTable().setSortDirection(dir);
305 viewer.getTable().setSortColumn(column);
306 viewer.refresh();
307 } catch (Exception exc) {
308 exc.printStackTrace();
309 }
310 }
311 };
312 return selectionAdapter;
313 }
314
315 /**
316 * To be overridden to enable sorting.
317 */
318 protected GenericTableComparator getComparator() {
319 return null;
320 }
321
322 @Override
323 public boolean isDirty() {
324 return false;
325 }
326
327 @Override
328 public void doSave(IProgressMonitor monitor) {
329 // TODO save the query in JCR?
330 }
331
332 @Override
333 public void doSaveAs() {
334 }
335
336 @Override
337 public boolean isSaveAsAllowed() {
338 return false;
339 }
340
341 /** Returns the injected current session */
342 protected Session getSession() {
343 return session;
344 }
345
346 /* DEPENDENCY INJECTION */
347 public void setSession(Session session) {
348 this.session = session;
349 }
350 }