From 111e463d51e2cdf841264b6cc7f1fa30f35afed8 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 22 Jan 2011 19:05:43 +0000 Subject: [PATCH] JCR query editor git-svn-id: https://svn.argeo.org/commons/trunk@4067 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../org.argeo.eclipse.ui.jcr/.classpath | 7 + .../plugins/org.argeo.eclipse.ui.jcr/.project | 28 +++ .../.settings/org.eclipse.jdt.core.prefs | 8 + .../.settings/org.eclipse.pde.core.prefs | 4 + .../org.argeo.eclipse.ui.jcr/build.properties | 4 + .../plugins/org.argeo.eclipse.ui.jcr/pom.xml | 80 +++++++ .../commands/OpenGenericJcrQueryEditor.java | 30 +++ .../jcr/editors/AbstractJcrQueryEditor.java | 201 ++++++++++++++++++ .../ui/jcr/editors/GenericJcrQueryEditor.java | 41 ++++ .../ui/jcr/editors/JcrQueryEditorInput.java | 53 +++++ eclipse/plugins/org.argeo.eclipse.ui/pom.xml | 11 +- eclipse/plugins/pom.xml | 1 + .../jackrabbit/JackrabbitContainer.java | 37 +++- 13 files changed, 501 insertions(+), 4 deletions(-) create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/.project create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java create mode 100644 eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath new file mode 100644 index 000000000..92f19d2ff --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.project b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.project new file mode 100644 index 000000000..d15268372 --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.project @@ -0,0 +1,28 @@ + + + org.argeo.eclipse.ui.jcr + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..57d3f0066 --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Sat Jan 22 14:25:47 CET 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 000000000..81635e90f --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,4 @@ +#Sat Jan 22 14:25:47 CET 2011 +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties b/eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties new file mode 100644 index 000000000..5fc538bc8 --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties @@ -0,0 +1,4 @@ +source.. = src/main/java/ +output.. = target/classes/ +bin.includes = META-INF/,\ + . diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml b/eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml new file mode 100644 index 000000000..4f041eeaa --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + + org.argeo.commons.eclipse + 0.2.2-SNAPSHOT + plugins + .. + + org.argeo.eclipse.ui.jcr + Commons Eclipse UI JCR + jar + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.felix + maven-bundle-plugin + ${version.maven-bundle-plugin} + + + lazy + + org.eclipse.swt, + * + + + + + + + + + + + org.argeo.commons.eclipse + org.argeo.eclipse.dep.common + 0.2.2-SNAPSHOT + + + + + org.argeo.dep.osgi + org.argeo.dep.osgi.jcr + + + + + org.argeo.commons.eclipse + org.argeo.eclipse.dep.rcp + ${version.argeo-commons} + provided + + + + + org.argeo.commons.basic + org.argeo.basic.nodeps + 0.2.2-SNAPSHOT + + + + + org.slf4j + com.springsource.slf4j.org.apache.commons.logging + + + + diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java new file mode 100644 index 000000000..116974706 --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java @@ -0,0 +1,30 @@ +package org.argeo.eclipse.ui.jcr.commands; + +import org.argeo.eclipse.ui.jcr.editors.JcrQueryEditorInput; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Open a JCR query editor. */ +public class OpenGenericJcrQueryEditor extends AbstractHandler { + private String editorId; + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + JcrQueryEditorInput editorInput = new JcrQueryEditorInput("", null); + IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow( + event).getActivePage(); + activePage.openEditor(editorInput, editorId); + } catch (Exception e) { + throw new ExecutionException("Cannot open editor", e); + } + return null; + } + + public void setEditorId(String editorId) { + this.editorId = editorId; + } + +} diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java new file mode 100644 index 000000000..802fc0f12 --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java @@ -0,0 +1,201 @@ +package org.argeo.eclipse.ui.jcr.editors; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.QueryResult; +import javax.jcr.query.Row; +import javax.jcr.query.RowIterator; + +import org.argeo.ArgeoException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; + +/** Executes any JCR query. */ +public abstract class AbstractJcrQueryEditor extends EditorPart { + protected String initialQuery; + protected String initialQueryType; + + private Session session; + + private TableViewer viewer; + private List tableViewerColumns = new ArrayList(); + + protected abstract void createQueryForm(Composite parent); + + @Override + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + JcrQueryEditorInput editorInput = (JcrQueryEditorInput) input; + initialQuery = editorInput.getQuery(); + initialQueryType = editorInput.getQueryType(); + setSite(site); + setInput(editorInput); + } + + @Override + public final void createPartControl(final Composite parent) { + parent.setLayout(new FillLayout()); + + SashForm sashForm = new SashForm(parent, SWT.VERTICAL); + sashForm.setSashWidth(2); + sashForm.setLayout(new FillLayout()); + + Composite top = new Composite(sashForm, SWT.NONE); + top.setLayout(new GridLayout(1, false)); + // Device device = Display.getCurrent(); + // Color red = new Color(device, 255, 0, 0); + // top.setBackground(red); + createQueryForm(top); + + Composite bottom = new Composite(sashForm, SWT.NONE); + bottom.setLayout(new GridLayout(1, false)); + sashForm.setWeights(new int[] { 30, 70 }); + + viewer = new TableViewer(bottom); + viewer.getTable().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + viewer.getTable().setHeaderVisible(true); + viewer.setContentProvider(new QueryResultContentProvider()); + // viewer.setLabelProvider(new QueryResultLabelProvider()); + viewer.setInput(getEditorSite()); + } + + protected void executeQuery(String statement) { + try { + QueryResult qr = session.getWorkspace().getQueryManager() + .createQuery(statement, initialQueryType).execute(); + + // remove previous columns + for (TableViewerColumn tvc : tableViewerColumns) + tvc.getColumn().dispose(); + + for (final String columnName : qr.getColumnNames()) { + TableViewerColumn tvc = new TableViewerColumn(viewer, SWT.NONE); + tvc.getColumn().setWidth(50); + tvc.getColumn().setText(columnName); + tvc.setLabelProvider(new ColumnLabelProvider() { + + public String getText(Object element) { + Row row = (Row) element; + try { + return row.getValue(columnName).getString(); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot display row " + + row, e); + } + } + + public Image getImage(Object element) { + return null; + } + }); + tableViewerColumns.add(tvc); + } + + viewer.setInput(qr); + } catch (RepositoryException e) { + ErrorDialog.openError(null, "Error", "Cannot execute JCR query: " + + statement, new Status(IStatus.ERROR, + "org.argeo.eclipse.ui.jcr", e.getMessage())); + // throw new ArgeoException("Cannot execute JCR query " + statement, + // e); + } + } + + private class QueryResultContentProvider implements + IStructuredContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getElements(Object inputElement) { + if (!(inputElement instanceof QueryResult)) + return new String[] {}; + + try { + QueryResult queryResult = (QueryResult) inputElement; + List rows = new ArrayList(); + RowIterator rit = queryResult.getRows(); + while (rit.hasNext()) { + rows.add(rit.nextRow()); + } + + // List elems = new ArrayList(); + // NodeIterator nit = queryResult.getNodes(); + // while (nit.hasNext()) { + // elems.add(nit.nextNode()); + // } + return rows.toArray(); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot read query result", e); + } + } + + } + + // private class QueryResultLabelProvider extends LabelProvider implements + // ITableLabelProvider { + // public String getColumnText(Object element, int columnIndex) { + // Row row = (Row) element; + // try { + // return row.getValues()[columnIndex].toString(); + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot display row " + row, e); + // } + // } + // + // public Image getColumnImage(Object element, int columnIndex) { + // return null; + // } + // + // } + + @Override + public boolean isDirty() { + return false; + } + + @Override + public void doSave(IProgressMonitor monitor) { + // TODO save the query in JCR? + + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + public void setSession(Session session) { + this.session = session; + } + +} diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java new file mode 100644 index 000000000..a02268b7d --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java @@ -0,0 +1,41 @@ +package org.argeo.eclipse.ui.jcr.editors; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +/** Executes any JCR query. */ +public class GenericJcrQueryEditor extends AbstractJcrQueryEditor { + private Text queryField; + + @Override + public void createQueryForm(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + + queryField = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP); + queryField.setText(initialQuery); + queryField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Button execute = new Button(parent, SWT.PUSH); + execute.setText("Execute"); + + Listener executeListener = new Listener() { + public void handleEvent(Event event) { + executeQuery(queryField.getText()); + } + }; + + execute.addListener(SWT.Selection, executeListener); + // queryField.addListener(SWT.DefaultSelection, executeListener); + } + + @Override + public void setFocus() { + queryField.setFocus(); + } +} diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java new file mode 100644 index 000000000..45c2a68d3 --- /dev/null +++ b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java @@ -0,0 +1,53 @@ +package org.argeo.eclipse.ui.jcr.editors; + +import javax.jcr.query.Query; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +public class JcrQueryEditorInput implements IEditorInput { + private final String query; + private final String queryType; + + public JcrQueryEditorInput(String query, String queryType) { + this.query = query; + if (queryType == null) + this.queryType = Query.JCR_SQL2; + else + this.queryType = queryType; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return query; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return query; + } + + public String getQuery() { + return query; + } + + public String getQueryType() { + return queryType; + } + +} diff --git a/eclipse/plugins/org.argeo.eclipse.ui/pom.xml b/eclipse/plugins/org.argeo.eclipse.ui/pom.xml index ee5398252..e4adbdcd2 100644 --- a/eclipse/plugins/org.argeo.eclipse.ui/pom.xml +++ b/eclipse/plugins/org.argeo.eclipse.ui/pom.xml @@ -55,10 +55,17 @@ 0.2.2-SNAPSHOT + + + org.argeo.dep.osgi + org.argeo.dep.osgi.jcr + + - org.eclipse.ui - org.eclipse.ui + org.argeo.commons.eclipse + org.argeo.eclipse.dep.rcp + ${version.argeo-commons} provided diff --git a/eclipse/plugins/pom.xml b/eclipse/plugins/pom.xml index 98f6bcb25..f8facd6f4 100644 --- a/eclipse/plugins/pom.xml +++ b/eclipse/plugins/pom.xml @@ -12,6 +12,7 @@ pom org.argeo.eclipse.ui + org.argeo.eclipse.ui.jcr diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java index f06163f34..979788940 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java @@ -16,9 +16,13 @@ package org.argeo.server.jackrabbit; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.jcr.Credentials; @@ -34,20 +38,23 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.commons.NamespaceHelper; +import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.core.RepositoryImpl; import org.apache.jackrabbit.core.TransientRepository; import org.apache.jackrabbit.core.config.RepositoryConfig; import org.argeo.ArgeoException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; /** * Wrapper around a Jackrabbit repository which allows to configure it in Spring * and expose it as a {@link Repository}. */ public class JackrabbitContainer implements InitializingBean, DisposableBean, - Repository { + Repository, ResourceLoaderAware { private Log log = LogFactory.getLog(JackrabbitContainer.class); private Resource configuration; @@ -57,10 +64,24 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, private Repository repository; + private ResourceLoader resourceLoader; + + /** Node type definitions in CND format */ + private List cnds = new ArrayList(); + private List cndFiles = new ArrayList(); + /** Namespaces to register: key is prefix, value namespace */ private Map namespaces = new HashMap(); public void afterPropertiesSet() throws Exception { + // Load cnds as resources + for (String resUrl : cndFiles) { + + Resource res = resourceLoader.getResource(resUrl); + byte[] arr = IOUtils.toByteArray(res.getInputStream()); + cnds.add(arr); + } + if (inMemory && homeDirectory.exists()) { FileUtils.deleteDirectory(homeDirectory); log.warn("Deleted Jackrabbit home directory " + homeDirectory); @@ -146,11 +167,19 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, try { NamespaceHelper namespaceHelper = new NamespaceHelper(session); namespaceHelper.registerNamespaces(namespaces); - } catch (RepositoryException e) { + + for (byte[] arr : cnds) + CndImporter.registerNodeTypes(new InputStreamReader( + new ByteArrayInputStream(arr)), session); + } catch (Exception e) { throw new ArgeoException("Cannot process new session", e); } } + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + public boolean isStandardDescriptor(String key) { return repository.isStandardDescriptor(key); } @@ -184,4 +213,8 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, this.namespaces = namespaces; } + public void setCndFiles(List cndFiles) { + this.cndFiles = cndFiles; + } + } -- 2.30.2