2 * Copyright (C) 2007-2012 Argeo GmbH
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
.cms
.ui
.workbench
.internal
.jcr
.parts
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
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
;
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
;
56 /** Executes any JCR query. */
57 public abstract class AbstractJcrQueryEditor
extends EditorPart
{
58 private final static Log log
= LogFactory
59 .getLog(AbstractJcrQueryEditor
.class);
61 protected String initialQuery
;
62 protected String initialQueryType
;
64 /* DEPENDENCY INJECTION */
65 private Session session
;
68 private TableViewer viewer
;
69 private List
<TableViewerColumn
> tableViewerColumns
= new ArrayList
<TableViewerColumn
>();
70 private GenericTableComparator comparator
;
72 /** Override to layout a form enabling the end user to build his query */
73 protected abstract void createQueryForm(Composite parent
);
76 public void init(IEditorSite site
, IEditorInput input
)
77 throws PartInitException
{
78 JcrQueryEditorInput editorInput
= (JcrQueryEditorInput
) input
;
79 initialQuery
= editorInput
.getQuery();
80 initialQueryType
= editorInput
.getQueryType();
82 setInput(editorInput
);
86 public final void createPartControl(final Composite parent
) {
87 parent
.setLayout(new FillLayout());
89 SashForm sashForm
= new SashForm(parent
, SWT
.VERTICAL
);
90 sashForm
.setSashWidth(4);
91 sashForm
.setLayout(new FillLayout());
93 Composite top
= new Composite(sashForm
, SWT
.NONE
);
94 GridLayout gl
= new GridLayout(1, false);
99 Composite bottom
= new Composite(sashForm
, SWT
.NONE
);
100 bottom
.setLayout(new GridLayout(1, false));
101 sashForm
.setWeights(getWeights());
103 viewer
= new TableViewer(bottom
);
104 viewer
.getTable().setLayoutData(
105 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
106 viewer
.getTable().setHeaderVisible(true);
107 viewer
.setContentProvider(getQueryResultContentProvider());
108 viewer
.setInput(getEditorSite());
110 if (getComparator() != null) {
111 comparator
= getComparator();
112 viewer
.setComparator(comparator
);
114 if (getTableDoubleClickListener() != null)
115 viewer
.addDoubleClickListener(getTableDoubleClickListener());
119 protected void executeQuery(String statement
) {
121 if (log
.isDebugEnabled())
122 log
.debug("Query : " + statement
);
124 QueryResult qr
= session
.getWorkspace().getQueryManager()
125 .createQuery(statement
, initialQueryType
).execute();
127 // remove previous columns
128 for (TableViewerColumn tvc
: tableViewerColumns
)
129 tvc
.getColumn().dispose();
132 for (final String columnName
: qr
.getColumnNames()) {
133 TableViewerColumn tvc
= new TableViewerColumn(viewer
, SWT
.NONE
);
134 configureColumn(columnName
, tvc
, i
);
135 tvc
.setLabelProvider(getLabelProvider(columnName
));
136 tableViewerColumns
.add(tvc
);
140 // Must create a local list: QueryResults can only be read once.
142 List
<Row
> rows
= new ArrayList
<Row
>();
143 RowIterator rit
= qr
.getRows();
144 while (rit
.hasNext()) {
145 rows
.add(rit
.nextRow());
147 viewer
.setInput(rows
);
148 } catch (RepositoryException e
) {
149 throw new EclipseUiException("Cannot read query result", e
);
152 } catch (RepositoryException e
) {
153 ErrorDialog
.openError(null, "Error", "Cannot execute JCR query: "
154 + statement
, new Status(IStatus
.ERROR
,
155 "org.argeo.eclipse.ui.jcr", e
.getMessage()));
160 * To be overidden to adapt size of form and result frames.
164 protected int[] getWeights() {
165 return new int[] { 30, 70 };
169 * To be overidden to implement a doubleclick Listener on one of the rows of
174 protected IDoubleClickListener
getTableDoubleClickListener() {
179 * To be overiden in order to implement a specific
180 * QueryResultContentProvider
182 protected IStructuredContentProvider
getQueryResultContentProvider() {
183 return new QueryResultContentProvider();
187 * Enable specific implementation for columns
189 protected List
<TableViewerColumn
> getTableViewerColumns() {
190 return tableViewerColumns
;
194 * Enable specific implementation for columns
196 protected TableViewer
getTableViewer() {
201 * To be overridden in order to configure column label providers .
203 protected ColumnLabelProvider
getLabelProvider(final String columnName
) {
204 return new ColumnLabelProvider() {
205 private static final long serialVersionUID
= -3539689333250152606L;
207 public String
getText(Object element
) {
208 Row row
= (Row
) element
;
210 return row
.getValue(columnName
).getString();
211 } catch (RepositoryException e
) {
212 throw new EclipseUiException("Cannot display row " + row
, e
);
216 public Image
getImage(Object element
) {
223 * To be overridden in order to configure the columns.
225 * @deprecated use {@link
226 * org.argeo.eclipse.ui.jcr.editors.AbstractJcrQueryEditor.
227 * configureColumn(String jcrColumnName, TableViewerColumn
228 * column, int columnIndex)} instead
230 protected void configureColumn(String jcrColumnName
,
231 TableViewerColumn column
) {
232 column
.getColumn().setWidth(50);
233 column
.getColumn().setText(jcrColumnName
);
236 /** To be overridden in order to configure the columns. */
237 protected void configureColumn(String jcrColumnName
,
238 TableViewerColumn column
, int columnIndex
) {
239 column
.getColumn().setWidth(50);
240 column
.getColumn().setText(jcrColumnName
);
243 private class QueryResultContentProvider
implements
244 IStructuredContentProvider
{
245 private static final long serialVersionUID
= -5421095459600554741L;
247 public void dispose() {
250 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
253 public Object
[] getElements(Object inputElement
) {
255 if (inputElement
instanceof List
)
256 return ((List
<?
>) inputElement
).toArray();
258 // Never reached might be deleted in future release
259 if (!(inputElement
instanceof QueryResult
))
260 return new String
[] {};
263 QueryResult queryResult
= (QueryResult
) inputElement
;
264 List
<Row
> rows
= new ArrayList
<Row
>();
265 RowIterator rit
= queryResult
.getRows();
266 while (rit
.hasNext()) {
267 rows
.add(rit
.nextRow());
270 // List<Node> elems = new ArrayList<Node>();
271 // NodeIterator nit = queryResult.getNodes();
272 // while (nit.hasNext()) {
273 // elems.add(nit.nextNode());
275 return rows
.toArray();
276 } catch (RepositoryException e
) {
277 throw new EclipseUiException("Cannot read query result", e
);
284 * Might be used by children classes to sort columns.
290 protected SelectionAdapter
getSelectionAdapter(final TableColumn column
,
293 // A comparator must be define
294 if (comparator
== null)
297 SelectionAdapter selectionAdapter
= new SelectionAdapter() {
298 private static final long serialVersionUID
= 239829307927778349L;
301 public void widgetSelected(SelectionEvent e
) {
305 comparator
.setColumn(index
);
306 int dir
= viewer
.getTable().getSortDirection();
307 if (viewer
.getTable().getSortColumn() == column
) {
308 dir
= dir
== SWT
.UP ? SWT
.DOWN
: SWT
.UP
;
313 viewer
.getTable().setSortDirection(dir
);
314 viewer
.getTable().setSortColumn(column
);
316 } catch (Exception exc
) {
317 exc
.printStackTrace();
321 return selectionAdapter
;
325 * To be overridden to enable sorting.
327 protected GenericTableComparator
getComparator() {
332 public boolean isDirty() {
337 public void doSave(IProgressMonitor monitor
) {
338 // TODO save the query in JCR?
342 public void doSaveAs() {
346 public boolean isSaveAsAllowed() {
350 /** Returns the injected current session */
351 protected Session
getSession() {
355 /* DEPENDENCY INJECTION */
356 public void setSession(Session session
) {
357 this.session
= session
;