From: Bruno Sinou Date: Wed, 14 Sep 2011 16:58:32 +0000 (+0000) Subject: + refactoring of the JCR UI Model (in a MVC point of view) X-Git-Tag: argeo-commons-2.1.30~1156 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=c0b7b3f9d1781d074ab35d24017042fa9415e1e4;p=lgpl%2Fargeo-commons.git + refactoring of the JCR UI Model (in a MVC point of view) + add a command to enable to get size of a repository + clean jcr.ui.explorer bundle. git-svn-id: https://svn.argeo.org/commons/trunk@4739 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/.classpath b/eclipse/runtime/org.argeo.eclipse.ui.jcr/.classpath index 92f19d2ff..d3d5c8095 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.jcr/.classpath +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/.classpath @@ -3,5 +3,6 @@ + diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/build.properties b/eclipse/runtime/org.argeo.eclipse.ui.jcr/build.properties index b3eb07b43..0f2736b3a 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.jcr/build.properties +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/build.properties @@ -1,4 +1,5 @@ -source.. = src/main/java/ +source.. = src/main/java/,\ + src/main/resources output.. = target/classes/ bin.includes = META-INF/,\ .,\ diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrUiPlugin.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrUiPlugin.java index a53368296..5f333f71d 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrUiPlugin.java +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrUiPlugin.java @@ -1,17 +1,26 @@ package org.argeo.eclipse.ui.jcr; +import java.util.ResourceBundle; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; public class JcrUiPlugin extends AbstractUIPlugin { + private final static Log log = LogFactory.getLog(JcrUiPlugin.class); + public final static String ID = "org.argeo.eclipse.ui.jcr"; + private ResourceBundle messages; + private static JcrUiPlugin plugin; public void start(BundleContext context) throws Exception { super.start(context); plugin = this; + messages = ResourceBundle.getBundle("org.argeo.eclipse.ui.jcr"); } public static JcrUiPlugin getDefault() { @@ -22,4 +31,25 @@ public class JcrUiPlugin extends AbstractUIPlugin { return imageDescriptorFromPlugin(ID, path); } + /** Returns the internationalized label for the given key */ + public static String getMessage(String key) { + try { + return getDefault().messages.getString(key); + } catch (NullPointerException npe) { + log.warn(key + " not found."); + return key; + } + } + + /** + * Gives access to the internationalization message bundle. Returns null in + * case the ClientUiPlugin is not started (for JUnit tests, by instance) + */ + public static ResourceBundle getMessagesBundle() { + if (getDefault() != null) + // To avoid NPE + return getDefault().messages; + else + return null; + } } diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/AddFileFolder.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/AddFileFolder.java index 487c2f629..dcc708f6a 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/AddFileFolder.java +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/AddFileFolder.java @@ -6,6 +6,7 @@ import javax.jcr.nodetype.NodeType; import org.argeo.eclipse.ui.ErrorFeedback; import org.argeo.eclipse.ui.dialogs.SingleValue; +import org.argeo.eclipse.ui.jcr.JcrUiPlugin; import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -26,6 +27,7 @@ public class AddFileFolder extends AbstractHandler { if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof Node) { String folderName = SingleValue.ask("Folder name", "Enter folder name"); @@ -42,7 +44,8 @@ public class AddFileFolder extends AbstractHandler { } } } else { - ErrorFeedback.show("Can only add file folder to a node"); + ErrorFeedback.show(JcrUiPlugin + .getMessage("errorUnvalidNtFolderNodeType")); } } return null; diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/resources/org/argeo/eclipse/ui/jcr/messages.properties b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/resources/org/argeo/eclipse/ui/jcr/messages.properties new file mode 100644 index 000000000..a24aa3861 --- /dev/null +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/resources/org/argeo/eclipse/ui/jcr/messages.properties @@ -0,0 +1,7 @@ +## English labels for Agreo base JCR UI application + +## Generic labels + +## Errors +errorUnvalidNtFolderNodeType= Error: folder can only be created on a Jcr Node + diff --git a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java index 8989d69ad..c4e74a96f 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java +++ b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java @@ -33,19 +33,22 @@ public class TreeParent extends TreeObject { public synchronized void addChild(Object child) { loaded = true; children.add(child); - if (child instanceof TreeParent) - ((TreeParent) child).setParent(this); + // bsinou: was 'if (child instanceof TreeParent)' + if (child instanceof TreeObject) + ((TreeObject) child).setParent(this); } public synchronized void removeChild(Object child) { children.remove(child); if (child instanceof TreeParent) ((TreeParent) child).setParent(null); + // TODO: clear subtree recursively } public synchronized void clearChildren() { loaded = false; children.clear(); + // TODO: clear also the objects } public synchronized Object[] getChildren() { diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.classpath b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.classpath new file mode 100644 index 000000000..4a46cfabf --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.classpath @@ -0,0 +1,9 @@ + + + + + + + diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.project b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.project new file mode 100644 index 000000000..25ecae590 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.project @@ -0,0 +1,28 @@ + + + org.argeo.sandbox.ui.rap + + + + + + 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/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.settings/org.eclipse.jdt.core.prefs b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..480cda746 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Jun 20 10:19:50 CEST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/META-INF/MANIFEST.MF b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/META-INF/MANIFEST.MF new file mode 100644 index 000000000..b8e12e705 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Rap sandbox +Bundle-SymbolicName: org.argeo.sandbox.ui.rap;singleton:=true +Bundle-Version: 0.3.3.SNAPSHOT +Bundle-Activator: org.argeo.sandbox.ui.rap.Activator +Bundle-Vendor: Argeo +Require-Bundle: org.eclipse.rap.ui +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Import-Package: javax.servlet;version="2.4.0", + javax.servlet.http;version="2.4.0", + org.eclipse.equinox.http.servlet;version="1.1.0" + diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/applicationContext.xml b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/applicationContext.xml new file mode 100644 index 000000000..db1c6dd75 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/applicationContext.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/service-servlet.xml b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/service-servlet.xml new file mode 100644 index 000000000..7a052199e --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/service-servlet.xml @@ -0,0 +1,28 @@ + + + + + + + + osgiServiceController + + + + + + + org.eclipse.equinox.http.servlet.HttpServiceServlet + + + osgiService + + + \ No newline at end of file diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/web.xml b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/web.xml new file mode 100644 index 000000000..daa71c957 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/WEB-INF/web.xml @@ -0,0 +1,38 @@ + + + + Argeo OSGi TEST Webapp + + + + contextConfigLocation + /WEB-INF/applicationContext.xml + + + + Spring Context + org.springframework.web.context.ContextLoaderListener + + + contextClass + org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + + + + + service + org.springframework.web.servlet.DispatcherServlet + + contextClass + org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + + 1 + + + + service + /* + + diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/build.properties b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/build.properties new file mode 100644 index 000000000..885c233db --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/build.properties @@ -0,0 +1,6 @@ +source.. = src/main/java/ +output.. = target/classes/ +bin.includes = plugin.xml,\ + META-INF/,\ + WEB-INF/,\ + . diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/log4j.properties b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/log4j.properties new file mode 100644 index 000000000..b60e90665 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/log4j.properties @@ -0,0 +1,17 @@ +log4j.rootLogger=WARN, console + +## Levels +log4j.logger.org.argeo.sandbox.ui=TRACE + +# Apache Tomcat +log4j.logger.org.apache.catalina=DEBUG +log4j.logger.org.apache.coyote=INFO +log4j.logger.org.apache.tomcat=INFO + +## Appenders +# console is set to be a ConsoleAppender. +log4j.appender.console=org.apache.log4j.ConsoleAppender + +# console uses PatternLayout. +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - [%t] %c%n diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/plugin.xml b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/plugin.xml new file mode 100644 index 000000000..8b95c1b53 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/plugin.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/rap_sandbox_jetty.properties b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/rap_sandbox_jetty.properties new file mode 100644 index 000000000..962aa319c --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/rap_sandbox_jetty.properties @@ -0,0 +1,25 @@ +argeo.osgi.start=\ +org.springframework.osgi.extender,\ +com.springsource.javax.servlet,\ +org.eclipse.core.runtime,\ +org.eclipse.equinox.common,\ +org.eclipse.equinox.http.registry,\ +org.eclipse.equinox.launcher,\ +org.eclipse.equinox.http.jetty,\ +org.mortbay.jetty.server,\ +org.springframework.osgi.web.extender,\ +org.argeo.sandbox.ui.rap + + +##org.argeo.eclipse.ui,\ + +org.argeo.security.ui.initialPerspective=org.argeo.sandbox.ui.downloadTries + +eclipse.ignoreApp=true +osgi.noShutdown=true + +log4j.configuration=file:../../log4j.properties + +#org.eclipse.equinox.http.jetty.log.stderr.threshold=debug +org.osgi.service.http.port=9090 +# Demo test URL used with tomcat : http://localhost:9090/org.argeo.sandbox.ui/rap?startup=hello diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/rap_sandbox_tomcat.properties b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/rap_sandbox_tomcat.properties new file mode 100644 index 000000000..db4c91446 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/rap_sandbox_tomcat.properties @@ -0,0 +1,23 @@ +argeo.osgi.start=\ +org.springframework.osgi.extender,\ +com.springsource.javax.servlet,\ +org.eclipse.core.runtime,\ +org.eclipse.equinox.common,\ +org.eclipse.equinox.http.registry,\ +org.eclipse.equinox.launcher,\ +org.argeo.dep.osgi.catalina.start,\ +org.argeo.server.tomcat,\ +org.springframework.osgi.web.extender,\ +org.argeo.sandbox.ui.rap + + +##org.argeo.eclipse.ui,\ + +org.argeo.security.ui.initialPerspective=org.argeo.sandbox.ui.downloadTries + +eclipse.ignoreApp=true +osgi.noShutdown=true + +log4j.configuration=file:../../log4j.properties + +# Demo test URL used with tomcat : http://localhost:7070/org.argeo.rap.webapp/sebi diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Activator.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Activator.java new file mode 100644 index 000000000..4e0cae2f1 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Activator.java @@ -0,0 +1,68 @@ +package org.argeo.sandbox.ui.rap; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.argeo.sandbox.ui"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given plug-in + * relative path + * + * @param path + * the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Application.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Application.java new file mode 100644 index 000000000..401f1b111 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Application.java @@ -0,0 +1,19 @@ +package org.argeo.sandbox.ui.rap; + +import org.eclipse.rwt.lifecycle.IEntryPoint; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.application.WorkbenchAdvisor; + +/** + * This class controls all aspects of the application's execution + * and is contributed through the plugin.xml. + */ +public class Application implements IEntryPoint { + + public int createUI() { + Display display = PlatformUI.createDisplay(); + WorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor(); + return PlatformUI.createAndRunWorkbench( display, advisor ); + } +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationActionBarAdvisor.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationActionBarAdvisor.java new file mode 100644 index 000000000..55b74716a --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationActionBarAdvisor.java @@ -0,0 +1,24 @@ +package org.argeo.sandbox.ui.rap; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; + +/** + * Creates, adds and disposes actions for the menus and action bars of + * each workbench window. + */ +public class ApplicationActionBarAdvisor extends ActionBarAdvisor { + + public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) { + super(configurer); + } + + protected void makeActions(IWorkbenchWindow window) { + } + + protected void fillMenuBar(IMenuManager menuBar) { + } + +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationWorkbenchAdvisor.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationWorkbenchAdvisor.java new file mode 100644 index 000000000..4e98d3c6e --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationWorkbenchAdvisor.java @@ -0,0 +1,23 @@ +package org.argeo.sandbox.ui.rap; + +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** + * This workbench advisor creates the window advisor, and specifies the + * perspective id for the initial window. + */ +public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { + + private static final String PERSPECTIVE_ID = Perspective.ID; + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + IWorkbenchWindowConfigurer configurer) { + return new ApplicationWorkbenchWindowAdvisor(configurer); + } + + public String getInitialWindowPerspectiveId() { + return PERSPECTIVE_ID; + } +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationWorkbenchWindowAdvisor.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationWorkbenchWindowAdvisor.java new file mode 100644 index 000000000..0fd160d77 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/ApplicationWorkbenchWindowAdvisor.java @@ -0,0 +1,29 @@ +package org.argeo.sandbox.ui.rap; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** + * Configures the initial size and appearance of a workbench window. + */ +public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { + + public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { + super(configurer); + } + + public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) { + return new ApplicationActionBarAdvisor(configurer); + } + + public void preWindowOpen() { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + configurer.setInitialSize(new Point(400, 300)); + configurer.setShowCoolBar(false); + configurer.setShowStatusLine(false); + configurer.setTitle("Hello RAP"); + } +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Perspective.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Perspective.java new file mode 100644 index 000000000..dbc9560b6 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/Perspective.java @@ -0,0 +1,28 @@ +package org.argeo.sandbox.ui.rap; + +import org.argeo.sandbox.ui.rap.views.TestDownloadView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** + * Configures the perspective layout. This class is contributed through the + * plugin.xml. + */ +public class Perspective implements IPerspectiveFactory { + + public final static String ID = "org.argeo.sandbox.ui.downloadTries"; + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + // Create the main ui layout + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.4f, editorArea); + + // add the views to the corresponding place holder + left.addView(TestDownloadView.ID); + } +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/views/TestDownloadView.java b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/views/TestDownloadView.java new file mode 100644 index 000000000..180d58d39 --- /dev/null +++ b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/src/main/java/org/argeo/sandbox/ui/rap/views/TestDownloadView.java @@ -0,0 +1,22 @@ +package org.argeo.sandbox.ui.rap.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.part.ViewPart; + +public class TestDownloadView extends ViewPart { + public final static String ID = "org.argeo.sandbox.ui.testDownloadView"; + + @Override + public void createPartControl(Composite parent) { + Label label = new Label(parent, SWT.None); + label.setText("Test dowload"); + } + + @Override + public void setFocus() { + // TODO Auto-generated method stub + } + +} diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Activator.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Activator.class new file mode 100644 index 000000000..3c70499b7 Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Activator.class differ diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Application.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Application.class new file mode 100644 index 000000000..54da20b01 Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Application.class differ diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationActionBarAdvisor.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationActionBarAdvisor.class new file mode 100644 index 000000000..d3a314e14 Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationActionBarAdvisor.class differ diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationWorkbenchAdvisor.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationWorkbenchAdvisor.class new file mode 100644 index 000000000..c3845f241 Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationWorkbenchAdvisor.class differ diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationWorkbenchWindowAdvisor.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationWorkbenchWindowAdvisor.class new file mode 100644 index 000000000..efc99e451 Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/ApplicationWorkbenchWindowAdvisor.class differ diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Perspective.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Perspective.class new file mode 100644 index 000000000..c76b87e59 Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/Perspective.class differ diff --git a/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/views/TestDownloadView.class b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/views/TestDownloadView.class new file mode 100644 index 000000000..e7127fcfb Binary files /dev/null and b/sandbox/eclipse/plugins/org.argeo.sandbox.ui.rap/target/classes/org/argeo/sandbox/ui/rap/views/TestDownloadView.class differ diff --git a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/commands.xml b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/commands.xml index 0a6e9b68d..938451929 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/commands.xml +++ b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/commands.xml @@ -15,20 +15,23 @@ class="org.argeo.jcr.ui.explorer.commands.OpenGenericNodeEditor" scope="prototype"> + + + - - - + + + - - + + + + + + id="org.argeo.jcr.ui.explorer.addFolderNode" + name="Create folder"> + id="org.argeo.jcr.ui.explorer.deleteNodes" + name="Delete nodes"> @@ -116,12 +126,12 @@ style="push"> @@ -131,6 +141,16 @@ style="push" tooltip="Import files from the files sytem to the repository"> + + + + nodes = new ArrayList(); - Map repositories = repositoryRegister - .getRepositories(); - for (String name : repositories.keySet()) { - nodes.add(new RepositoryNode(name, repositories.get(name))); - } - return nodes.toArray(); - } else { + // if (parentElement instanceof Node) { + // return childrenNodes((Node) parentElement); + // } else if (parentElement instanceof RepositoryNode) { + // return ((RepositoryNode) parentElement).getChildren(); + // } else if (parentElement instanceof WorkspaceNode) { + // Session session = ((WorkspaceNode) parentElement).getSession(); + // if (session == null) + // return new Object[0]; + // + // try { + // return childrenNodes(session.getRootNode()); + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot retrieve root node of " + // + session, e); + // } + // } else if (parentElement instanceof RepositoryRegister) { + // RepositoryRegister repositoryRegister = (RepositoryRegister) + // parentElement; + // List nodes = new ArrayList(); + // Map repositories = repositoryRegister + // .getRepositories(); + // for (String name : repositories.keySet()) { + // nodes.add(new RepositoryNode(name, repositories.get(name))); + // } + // return nodes.toArray(); + + if (parentElement instanceof TreeParent) + return ((TreeParent) parentElement).getChildren(); + else { return new Object[0]; } } public Object getParent(Object element) { - try { - if (element instanceof Node) { - Node node = (Node) element; - if (!node.getPath().equals("/")) - return node.getParent(); - else - return null; - } - return null; - } catch (RepositoryException e) { + if (element instanceof TreeParent) { + return ((TreeParent) element).getParent(); + } else return null; - } } public boolean hasChildren(Object element) { - try { - if (element instanceof Node) { - return ((Node) element).hasNodes(); - } else if (element instanceof RepositoryNode) { - return ((RepositoryNode) element).hasChildren(); - } else if (element instanceof WorkspaceNode) { - return ((WorkspaceNode) element).getSession() != null; - } else if (element instanceof RepositoryRegister) { - return ((RepositoryRegister) element).getRepositories().size() > 0; - } - return false; - } catch (RepositoryException e) { - throw new ArgeoException("Cannot check children of " + element, e); + if (element instanceof RepositoriesNode) { + RepositoryRegister rr = ((RepositoriesNode) element) + .getRepositoryRegister(); + return rr.getRepositories().size() > 0; + } else if (element instanceof TreeParent) { + TreeParent tp = (TreeParent) element; + return tp.hasChildren(); + // } else if (element instanceof RepositoryNode) { + // return ((RepositoryNode) element).hasChildren(); + // } else if (element instanceof WorkspaceNode) { + // return ((WorkspaceNode) element).getSession() != null; } + return false; + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot check children of " + element, e); + // } } public void dispose() { @@ -118,20 +123,20 @@ public class NodeContentProvider implements ITreeContentProvider { public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } - protected Object[] childrenNodes(Node parentNode) { - try { - List children = new ArrayList(); - NodeIterator nit = parentNode.getNodes(); - while (nit.hasNext()) { - Node node = nit.nextNode(); - children.add(node); - } - Node[] arr = children.toArray(new Node[children.size()]); - Arrays.sort(arr, itemComparator); - return arr; - } catch (RepositoryException e) { - throw new ArgeoException("Cannot list children of " + parentNode, e); - } - } + // protected Object[] childrenNodes(Node parentNode) { + // try { + // List children = new ArrayList(); + // NodeIterator nit = parentNode.getNodes(); + // while (nit.hasNext()) { + // Node node = nit.nextNode(); + // children.add(node); + // } + // Node[] arr = children.toArray(new Node[children.size()]); + // Arrays.sort(arr, itemComparator); + // return arr; + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot list children of " + parentNode, e); + // } + // } } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/NodeLabelProvider.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/NodeLabelProvider.java index 6b9af8f75..cee1370ec 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/NodeLabelProvider.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/NodeLabelProvider.java @@ -4,9 +4,13 @@ import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.nodetype.NodeType; +import org.argeo.ArgeoException; import org.argeo.eclipse.ui.jcr.DefaultNodeLabelProvider; import org.argeo.eclipse.ui.jcr.JcrUiPlugin; -import org.argeo.jcr.RepositoryRegister; +import org.argeo.jcr.ui.explorer.model.RepositoriesNode; +import org.argeo.jcr.ui.explorer.model.RepositoryNode; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.model.WorkspaceNode; import org.eclipse.swt.graphics.Image; public class NodeLabelProvider extends DefaultNodeLabelProvider { @@ -15,10 +19,16 @@ public class NodeLabelProvider extends DefaultNodeLabelProvider { "icons/repositories.gif").createImage(); public String getText(Object element) { - if (element instanceof RepositoryRegister) { - return "Repositories"; + try { + if (element instanceof SingleJcrNode) { + SingleJcrNode sjn = (SingleJcrNode) element; + return getText(sjn.getNode()); + } else + return super.getText(element); + } catch (RepositoryException e) { + throw new ArgeoException( + "Unexpected JCR error while getting node name."); } - return super.getText(element); } protected String getText(Node node) throws RepositoryException { @@ -43,9 +53,14 @@ public class NodeLabelProvider extends DefaultNodeLabelProvider { return WorkspaceNode.WORKSPACE_DISCONNECTED; else return WorkspaceNode.WORKSPACE_CONNECTED; - } else if (element instanceof RepositoryRegister) { + } else if (element instanceof RepositoriesNode) { return REPOSITORIES; - } + } else if (element instanceof SingleJcrNode) + try { + return super.getImage(((SingleJcrNode) element).getNode()); + } catch (RepositoryException e) { + return null; + } return super.getImage(element); } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/RepositoryNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/RepositoryNode.java deleted file mode 100644 index 582e21855..000000000 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/RepositoryNode.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.argeo.jcr.ui.explorer.browser; - -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.SimpleCredentials; - -import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.jcr.JcrUiPlugin; -import org.eclipse.swt.graphics.Image; - -public class RepositoryNode extends TreeParent { - private final String name; - private final Repository repository; - private Session defaultSession = null; - public final static Image REPOSITORY_DISCONNECTED = JcrUiPlugin - .getImageDescriptor("icons/repository_disconnected.gif") - .createImage(); - public final static Image REPOSITORY_CONNECTED = JcrUiPlugin - .getImageDescriptor("icons/repository_connected.gif").createImage(); - - public RepositoryNode(String name, Repository repository) { - super(name); - this.name = name; - this.repository = repository; - } - - public void login() { - try { -// SimpleCredentials sc = new SimpleCredentials("root", -// "demo".toCharArray()); -// defaultSession = repository.login(sc); - defaultSession = repository.login(); - String[] wkpNames = defaultSession.getWorkspace() - .getAccessibleWorkspaceNames(); - for (String wkpName : wkpNames) { - if (wkpName.equals(defaultSession.getWorkspace().getName())) - addChild(new WorkspaceNode(repository, wkpName, - defaultSession)); - else - addChild(new WorkspaceNode(repository, wkpName)); - } - } catch (RepositoryException e) { - throw new ArgeoException("Cannot connect to repository " + name, e); - } - } - - public Session getDefaultSession() { - return defaultSession; - } - -} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/WorkspaceNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/WorkspaceNode.java deleted file mode 100644 index 4bff1674f..000000000 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/WorkspaceNode.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.argeo.jcr.ui.explorer.browser; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Workspace; -import javax.jcr.observation.EventIterator; -import javax.jcr.observation.EventListener; - -import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.jcr.JcrUiPlugin; -import org.eclipse.swt.graphics.Image; - -/** - * Wraps a JCR {@link Workspace}, or more precisely a {@link Session} to it. - * Implicitly also the root node of this session. - */ -public class WorkspaceNode extends TreeParent implements EventListener { - private final String name; - private final Repository repository; - private Session session = null; - public final static Image WORKSPACE_DISCONNECTED = JcrUiPlugin - .getImageDescriptor("icons/workspace_disconnected.png") - .createImage(); - public final static Image WORKSPACE_CONNECTED = JcrUiPlugin - .getImageDescriptor("icons/workspace_connected.png").createImage(); - - public WorkspaceNode(Repository repository, String name) { - this(repository, name, null); - } - - public WorkspaceNode(Repository repository, String name, Session session) { - super(name); - this.name = name; - this.repository = repository; - this.session = session; - if (session != null) - processNewSession(session); - } - - public Session getSession() { - return session; - } - - public Node getRootNode() { - try { - if (session != null) - return session.getRootNode(); - else - return null; - } catch (RepositoryException e) { - throw new ArgeoException("Cannot get root node of workspace " - + name, e); - } - } - - public void login() { - try { - logout(); - session = repository.login(name); - processNewSession(session); - } catch (RepositoryException e) { - throw new ArgeoException("Cannot connect to repository " + name, e); - } - } - - public void logout() { - try { - if (session != null && session.isLive()) { - session.getWorkspace().getObservationManager() - .removeEventListener(this); - session.logout(); - } - } catch (RepositoryException e) { - throw new ArgeoException("Cannot connect to repository " + name, e); - } - } - - public void onEvent(final EventIterator events) { - // if (session == null) - // return; - // Display.getDefault().syncExec(new Runnable() { - // public void run() { - // while (events.hasNext()) { - // Event event = events.nextEvent(); - // try { - // String path = event.getPath(); - // String parentPath = path.substring(0, - // path.lastIndexOf('/')); - // final Object parent; - // if (parentPath.equals("/") || parentPath.equals("")) - // parent = this; - // else if (session.itemExists(parentPath)){ - // parent = session.getItem(parentPath); - // ((Item)parent).refresh(false); - // } - // else - // parent = null; - // if (parent != null) { - // nodesViewer.refresh(parent); - // } - // - // } catch (RepositoryException e) { - // log.warn("Error processing event " + event, e); - // } - // } - // } - // }); - } - - protected void processNewSession(Session session) { - // try { - // ObservationManager observationManager = session.getWorkspace() - // .getObservationManager(); - // observationManager.addEventListener(this, Event.NODE_ADDED - // | Event.NODE_REMOVED, "/", true, null, null, false); - // } catch (RepositoryException e) { - // throw new ArgeoException("Cannot process new session " - // + session, e); - // } - } - -} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/AddFolderNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/AddFolderNode.java new file mode 100644 index 000000000..ed81c88d9 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/AddFolderNode.java @@ -0,0 +1,56 @@ +package org.argeo.jcr.ui.explorer.commands; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.eclipse.ui.ErrorFeedback; +import org.argeo.eclipse.ui.dialogs.SingleValue; +import org.argeo.eclipse.ui.jcr.JcrUiPlugin; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Adds a node of type nt:folder */ +public class AddFolderNode extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + + if (obj instanceof SingleJcrNode) { + String folderName = SingleValue.ask("Folder name", + "Enter folder name"); + if (folderName != null) { + SingleJcrNode sjn = (SingleJcrNode) obj; + Node parentNode = sjn.getNode(); + try { + Node newNode = parentNode.addNode(folderName, + NodeType.NT_FOLDER); + parentNode.getSession().save(); + view.nodeAdded(sjn); + } catch (RepositoryException e) { + ErrorFeedback.show("Cannot create folder " + folderName + + " under " + parentNode, e); + } + } + } else { + ErrorFeedback.show(JcrUiPlugin + .getMessage("errorUnvalidNtFolderNodeType")); + } + } + return null; + } + +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/DeleteNodes.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/DeleteNodes.java new file mode 100644 index 000000000..a0e106906 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/DeleteNodes.java @@ -0,0 +1,83 @@ +package org.argeo.jcr.ui.explorer.commands; + +import java.util.Iterator; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.ErrorFeedback; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.model.WorkspaceNode; +import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Deletes the selected nodes: both in the JCR repository and in the UI view. + * Warning no check is done, except implementation dependent native checks, + * handle with care. + */ +public class DeleteNodes extends AbstractHandler { + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && selection instanceof IStructuredSelection) { + Iterator it = ((IStructuredSelection) selection).iterator(); + Object obj = null; + SingleJcrNode ancestor = null; + WorkspaceNode rootAncestor = null; + try { + while (it.hasNext()) { + obj = it.next(); + if (obj instanceof SingleJcrNode) { + // Cache objects + SingleJcrNode sjn = (SingleJcrNode) obj; + TreeParent tp = (TreeParent) sjn.getParent(); + Node node = sjn.getNode(); + + // Jcr Remove + node.remove(); + node.getSession().save(); + // UI remove + tp.removeChild(sjn); + + // Check if the parent is the root node + if (tp instanceof WorkspaceNode) + rootAncestor = (WorkspaceNode) tp; + else + ancestor = getOlder(ancestor, (SingleJcrNode) tp); + } + } + if (rootAncestor != null) + view.nodeRemoved(rootAncestor); + else if (ancestor != null) + view.nodeRemoved(ancestor); + } catch (Exception e) { + ErrorFeedback.show("Cannot delete selected node ", e); + } + } + return null; + } + + private SingleJcrNode getOlder(SingleJcrNode A, SingleJcrNode B) { + try { + if (A == null) + return B == null ? null : B; + // Todo enhanced this method + else + return A.getNode().getDepth() <= B.getNode().getDepth() ? A : B; + } catch (RepositoryException re) { + throw new ArgeoException("Cannot find ancestor", re); + } + } +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/GetNodeSize.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/GetNodeSize.java new file mode 100644 index 000000000..5dab8cf72 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/GetNodeSize.java @@ -0,0 +1,70 @@ +package org.argeo.jcr.ui.explorer.commands; + +import javax.jcr.Node; + +import org.argeo.eclipse.ui.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.ui.explorer.JcrExplorerPlugin; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.model.WorkspaceNode; +import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Opens the generic node editor. */ +public class GetNodeSize extends AbstractHandler { + // private final static Log log = LogFactory.getLog(GetNodeSize.class); + + public final static String ID = "org.argeo.jcr.ui.explorer.getNodeSize"; + public final static String DEFAULT_ICON_REL_PATH = "icons/getSize.gif"; + public final static String DEFAULT_LABEL = JcrExplorerPlugin + .getMessage("getNodeSizeCmdLbl"); + + public Object execute(ExecutionEvent event) throws ExecutionException { + // JcrUtils.getRepositoryByAlias(repositoryRegister, + // ArgeoJcrConstants.ALIAS_NODE); + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + + // We only get + IStructuredSelection iss = (IStructuredSelection) selection; + if (iss.size() > 1) + ErrorFeedback.show(JcrExplorerPlugin + .getMessage("warningInvalidMultipleSelection"), null); + + long size = 0; + Node node; + if (iss.getFirstElement() instanceof SingleJcrNode) + node = ((SingleJcrNode) iss.getFirstElement()).getNode(); + else if (iss.getFirstElement() instanceof WorkspaceNode) + node = ((WorkspaceNode) iss.getFirstElement()).getRootNode(); + else + // unvalid object type + return null; + + size = JcrUtils.getNodeApproxSize(node); + + String[] labels = { "OK" }; + Shell shell = HandlerUtil.getActiveWorkbenchWindow(event) + .getShell(); + MessageDialog md = new MessageDialog(shell, "Node size", null, + "Node size is: " + size / 1024 + " KB", + MessageDialog.INFORMATION, labels, 0); + md.open(); + } + return null; + } +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/ImportFileSystem.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/ImportFileSystem.java index e52694a1c..52ceb9047 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/ImportFileSystem.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/ImportFileSystem.java @@ -3,7 +3,11 @@ package org.argeo.jcr.ui.explorer.commands; import javax.jcr.Node; import org.argeo.eclipse.ui.ErrorFeedback; -import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.jcr.ui.explorer.JcrExplorerPlugin; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.model.WorkspaceNode; +import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser; import org.argeo.jcr.ui.explorer.wizards.ImportFileSystemWizard; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -18,23 +22,29 @@ public class ImportFileSystem extends AbstractHandler { public Object execute(ExecutionEvent event) throws ExecutionException { ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) .getActivePage().getSelection(); - AbstractJcrBrowser view = (AbstractJcrBrowser) HandlerUtil + GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil .getActiveWorkbenchWindow(event).getActivePage() .findView(HandlerUtil.getActivePartId(event)); if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { Object obj = ((IStructuredSelection) selection).getFirstElement(); try { - if (obj instanceof Node) { - Node folder = (Node) obj; + Node folder = null; + if (obj instanceof SingleJcrNode) { + folder = ((SingleJcrNode) obj).getNode(); + } else if (obj instanceof WorkspaceNode) { + folder = ((WorkspaceNode) obj).getRootNode(); + } else { + ErrorFeedback.show(JcrExplorerPlugin + .getMessage("warningInvalidNodeToImport")); + } + if (folder != null) { ImportFileSystemWizard wizard = new ImportFileSystemWizard( folder); WizardDialog dialog = new WizardDialog( HandlerUtil.getActiveShell(event), wizard); dialog.open(); - view.refresh(folder); - } else { - ErrorFeedback.show("Can only import to a node"); + view.nodeAdded((TreeParent) obj); } } catch (Exception e) { ErrorFeedback.show("Cannot import files to " + obj, e); @@ -42,5 +52,4 @@ public class ImportFileSystem extends AbstractHandler { } return null; } - } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoriesNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoriesNode.java new file mode 100644 index 000000000..559c8aa73 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoriesNode.java @@ -0,0 +1,65 @@ +package org.argeo.jcr.ui.explorer.model; + +import java.util.Map; + +import javax.jcr.Repository; +import javax.jcr.RepositoryFactory; + +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.jcr.RepositoryRegister; + +/** + * UI Tree component. Implements the Argeo abstraction of a + * {@link RepositoryFactory} that enable a user to "mount" various repositories + * in a single Tree like View. It is usually meant to be at the root of the UI + * Tree and thus {@link getParent()} method will return null. + * + * The {@link RepositoryFactory} is injected at instantiation time and must be + * use get or register new {@link Repository} objects upon which a reference is + * kept here. + */ + +public class RepositoriesNode extends TreeParent { + private final String name; + private final RepositoryRegister repositoryRegister; + + public RepositoriesNode(String name, RepositoryRegister repositoryRegister, + TreeParent parent) { + super(name); + this.name = name; + this.repositoryRegister = repositoryRegister; + } + + /** + * Override normal behaviour to initialize the various repositories only at + * request time + */ + @Override + public synchronized Object[] getChildren() { + if (isLoaded()) { + return super.getChildren(); + } else { + // initialize current object + Map refRepos = repositoryRegister + .getRepositories(); + for (String name : refRepos.keySet()) { + super.addChild(new RepositoryNode(name, refRepos.get(name), + this)); + } + return super.getChildren(); + } + } + + public void registerNewRepository(String alias, Repository repository) { + // TODO: implement this + // Create a new RepositoryNode Object + // add it + // super.addChild(new RepositoriesNode(...)); + } + + /** Returns the {@link RepositoryRegister} wrapped by thgis object. */ + public RepositoryRegister getRepositoryRegister() { + return repositoryRegister; + } + +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoryNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoryNode.java new file mode 100644 index 000000000..97759a651 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoryNode.java @@ -0,0 +1,74 @@ +package org.argeo.jcr.ui.explorer.model; + +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.jcr.JcrUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** + * UI Tree component. Wraps a JCR {@link Repository}. It also keeps a reference + * to its parent Tree Ui component; typically the unique {@link Repositories} + * object of the current view to enable bi-directionnal browsing in the tree. + */ + +public class RepositoryNode extends TreeParent implements UiNode { + private String alias; + private final Repository repository; + private Session defaultSession = null; + public final static Image REPOSITORY_DISCONNECTED = JcrUiPlugin + .getImageDescriptor("icons/repository_disconnected.gif") + .createImage(); + public final static Image REPOSITORY_CONNECTED = JcrUiPlugin + .getImageDescriptor("icons/repository_connected.gif").createImage(); + + /** Create a new repository with alias = name */ + public RepositoryNode(String alias, Repository repository, TreeParent parent) { + this(alias, alias, repository, parent); + } + + /** Create a new repository with distinct name & alias */ + public RepositoryNode(String alias, String name, Repository repository, + TreeParent parent) { + super(name); + this.repository = repository; + setParent(parent); + this.alias = alias; + } + + public void login() { + try { + // SimpleCredentials sc = new SimpleCredentials("root", + // "demo".toCharArray()); + // defaultSession = repository.login(sc); + defaultSession = repository.login(); + String[] wkpNames = defaultSession.getWorkspace() + .getAccessibleWorkspaceNames(); + for (String wkpName : wkpNames) { + if (wkpName.equals(defaultSession.getWorkspace().getName())) + addChild(new WorkspaceNode(this, wkpName, defaultSession)); + else + addChild(new WorkspaceNode(this, wkpName)); + } + } catch (RepositoryException e) { + throw new ArgeoException("Cannot connect to repository " + alias, e); + } + } + + public Session getDefaultSession() { + return defaultSession; + } + + /** returns the {@link Repository} referenced by the current UI Node */ + public Repository getRepository() { + return repository; + } + + public String getAlias() { + return alias; + } + +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/SingleJcrNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/SingleJcrNode.java new file mode 100644 index 000000000..03ac52226 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/SingleJcrNode.java @@ -0,0 +1,103 @@ +package org.argeo.jcr.ui.explorer.model; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Workspace; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.TreeParent; + +/** + * UI Tree component. Wraps a node of a JCR {@link Workspace}. It also keeps a + * reference to its parent node that can either be a {@link WorkspaceNode}, a + * {@link SingleJcrNode} or null if the node is "mounted" as the root of the UI + * tree. + */ + +public class SingleJcrNode extends TreeParent implements UiNode { + + private final Node node; + private String alias = null; + + // keeps a local reference to the node's name to avoid exception when the + // session is lost + // private final String name; + + /** Creates a new UiNode in the UI Tree */ + public SingleJcrNode(TreeParent parent, Node node, String name) { + super(name); + setParent(parent); + this.node = node; + } + + /** + * Creates a new UiNode in the UI Tree, keeping a reference to the alias of + * the corresponding repository in the current UI environment. It is useful + * to be able to mount nodes as roots of the UI tree. + */ + public SingleJcrNode(TreeParent parent, Node node, String name, String alias) { + super(name); + setParent(parent); + this.node = node; + this.alias = alias; + } + + /** returns the node wrapped by the current Ui object */ + public Node getNode() { + return node; + } + + /** + * Returns the alias corresponding to the repository abstraction that + * contains current node. If the current object is mounted as root of the UI + * tree, the alias is stored in the object. Otherwise, we must browse the + * tree backward to the RepositoryNode. + * + * Alias is then cached in the current object so that next time it will be + * here. + */ + public String getAlias() { + if (alias == null) { + alias = ((UiNode) getParent()).getAlias(); + } + return alias; + } + + /** + * Override normal behaviour to initialize children only when first + * requested + */ + @Override + public synchronized Object[] getChildren() { + if (isLoaded()) { + return super.getChildren(); + } else { + // initialize current object + try { + NodeIterator ni = node.getNodes(); + while (ni.hasNext()) { + Node curNode = ni.nextNode(); + addChild(new SingleJcrNode(this, curNode, curNode.getName())); + } + return super.getChildren(); + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexcpected error while initializing children SingleJcrNode", + re); + } + } + } + + @Override + public boolean hasChildren() { + try { + return node.hasNodes(); + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexpected error while checking children node existence", + re); + } + } + +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/UiNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/UiNode.java new file mode 100644 index 000000000..175328e96 --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/UiNode.java @@ -0,0 +1,10 @@ +package org.argeo.jcr.ui.explorer.model; + +/** + * insure presence of the useful specific methods used in the building a UI Tree + * based on JCR repositories + */ +public interface UiNode { + + public String getAlias(); +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/WorkspaceNode.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/WorkspaceNode.java new file mode 100644 index 000000000..58c9c83bc --- /dev/null +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/WorkspaceNode.java @@ -0,0 +1,175 @@ +package org.argeo.jcr.ui.explorer.model; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Workspace; +import javax.jcr.observation.EventIterator; +import javax.jcr.observation.EventListener; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.jcr.JcrUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** + * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also + * keeps a reference to its parent {@link RepositoryNode}, to be able to + * retrieve alias of the current used repository + */ + +public class WorkspaceNode extends TreeParent implements EventListener, UiNode { + private Session session = null; + + public final static Image WORKSPACE_DISCONNECTED = JcrUiPlugin + .getImageDescriptor("icons/workspace_disconnected.png") + .createImage(); + public final static Image WORKSPACE_CONNECTED = JcrUiPlugin + .getImageDescriptor("icons/workspace_connected.png").createImage(); + + public WorkspaceNode(RepositoryNode parent, String name) { + this(parent, name, null); + } + + public WorkspaceNode(RepositoryNode parent, String name, Session session) { + super(name); + this.session = session; + if (session != null) + processNewSession(session); + setParent(parent); + } + + public Session getSession() { + return session; + } + + public Node getRootNode() { + try { + if (session != null) + return session.getRootNode(); + else + return null; + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get root node of workspace " + + getName(), e); + } + } + + public void login() { + try { + logout(); + session = ((RepositoryNode) getParent()).getRepository().login( + getName()); + processNewSession(session); + + } catch (RepositoryException e) { + throw new ArgeoException("Cannot connect to repository " + + getName(), e); + } + } + + public void logout() { + try { + if (session != null && session.isLive()) { + session.getWorkspace().getObservationManager() + .removeEventListener(this); + session.logout(); + } + } catch (RepositoryException e) { + throw new ArgeoException("Cannot connect to repository " + + getName(), e); + } + } + + /** Returns the alias of the parent Repository */ + public String getAlias() { + return ((UiNode) getParent()).getAlias(); + } + + @Override + public boolean hasChildren() { + try { + if (session == null) + return false; + else + return session.getRootNode().hasNodes(); + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexpected error while checking children node existence", + re); + } + } + + /** Override normal behaviour to initialize display of the workspace */ + @Override + public synchronized Object[] getChildren() { + if (isLoaded()) { + return super.getChildren(); + } else { + // initialize current object + try { + Node rootNode; + if (session == null) + return null; + else + rootNode = session.getRootNode(); + NodeIterator ni = rootNode.getNodes(); + while (ni.hasNext()) { + Node node = ni.nextNode(); + addChild(new SingleJcrNode(this, node, node.getName())); + } + return super.getChildren(); + } catch (RepositoryException e) { + throw new ArgeoException( + "Cannot initialize WorkspaceNode UI object." + + getName(), e); + } + } + } + + public void onEvent(final EventIterator events) { + // if (session == null) + // return; + // Display.getDefault().syncExec(new Runnable() { + // public void run() { + // while (events.hasNext()) { + // Event event = events.nextEvent(); + // try { + // String path = event.getPath(); + // String parentPath = path.substring(0, + // path.lastIndexOf('/')); + // final Object parent; + // if (parentPath.equals("/") || parentPath.equals("")) + // parent = this; + // else if (session.itemExists(parentPath)){ + // parent = session.getItem(parentPath); + // ((Item)parent).refresh(false); + // } + // else + // parent = null; + // if (parent != null) { + // nodesViewer.refresh(parent); + // } + // + // } catch (RepositoryException e) { + // log.warn("Error processing event " + event, e); + // } + // } + // } + // }); + } + + protected void processNewSession(Session session) { + // try { + // ObservationManager observationManager = session.getWorkspace() + // .getObservationManager(); + // observationManager.addEventListener(this, Event.NODE_ADDED + // | Event.NODE_REMOVED, "/", true, null, null, false); + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot process new session " + // + session, e); + // } + } + +} diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/GenericNodeDoubleClickListener.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/GenericNodeDoubleClickListener.java index 4418c09d7..85d229d44 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/GenericNodeDoubleClickListener.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/GenericNodeDoubleClickListener.java @@ -9,11 +9,11 @@ import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.specific.FileHandler; import org.argeo.jcr.ui.explorer.JcrExplorerPlugin; -import org.argeo.jcr.ui.explorer.browser.NodeContentProvider; -import org.argeo.jcr.ui.explorer.browser.RepositoryNode; -import org.argeo.jcr.ui.explorer.browser.WorkspaceNode; import org.argeo.jcr.ui.explorer.editors.GenericNodeEditor; import org.argeo.jcr.ui.explorer.editors.GenericNodeEditorInput; +import org.argeo.jcr.ui.explorer.model.RepositoryNode; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.model.WorkspaceNode; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; @@ -46,13 +46,17 @@ public class GenericNodeDoubleClickListener implements IDoubleClickListener { .getFirstElement(); if (obj instanceof RepositoryNode) { RepositoryNode rpNode = (RepositoryNode) obj; - rpNode.login(); - nodeViewer.refresh(obj); + if (rpNode.getChildren().length == 0) { + rpNode.login(); + nodeViewer.refresh(obj); + } + // else do nothing } else if (obj instanceof WorkspaceNode) { ((WorkspaceNode) obj).login(); nodeViewer.refresh(obj); - } else if (obj instanceof Node) { - Node node = (Node) obj; + } else if (obj instanceof SingleJcrNode) { + SingleJcrNode sjn = (SingleJcrNode) obj; + Node node = sjn.getNode(); try { if (node.isNodeType(NodeType.NT_FILE)) { // double click on a file node triggers its opening @@ -65,7 +69,7 @@ public class GenericNodeDoubleClickListener implements IDoubleClickListener { // TODO : enhanced that. ITreeContentProvider itcp = (ITreeContentProvider) nodeViewer .getContentProvider(); - jfp.setRootNodes((Object[]) itcp.getElements(null)); + // jfp.setRootNodes((Object[]) itcp.getElements(null)); fileHandler.openFile(name, id); } GenericNodeEditorInput gnei = new GenericNodeEditorInput(node); @@ -81,15 +85,4 @@ public class GenericNodeDoubleClickListener implements IDoubleClickListener { } } } - - // Enhance this method - private String getRepositoryAlias(Object element) { - NodeContentProvider ncp = (NodeContentProvider) nodeViewer - .getContentProvider(); - Object parent = element; - while (!(ncp.getParent(parent) instanceof RepositoryNode) - && parent != null) - parent = ncp.getParent(parent); - return parent == null ? null : ((RepositoryNode) parent).getName(); - } } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrFileProvider.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrFileProvider.java index 01fd634b5..568c75108 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrFileProvider.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrFileProvider.java @@ -1,21 +1,16 @@ package org.argeo.jcr.ui.explorer.utils; import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import javax.jcr.Node; import javax.jcr.Property; -import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.nodetype.NodeType; import org.apache.commons.io.IOUtils; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.specific.FileProvider; -import org.argeo.jcr.RepositoryRegister; -import org.argeo.jcr.ui.explorer.browser.RepositoryNode; +import org.argeo.jcr.ui.explorer.model.RepositoryNode; /** * Implements a FileProvider for UI purposes. Note that it might not be very @@ -39,25 +34,25 @@ public class JcrFileProvider implements FileProvider { * * @param repositoryNode */ - public void setRootNodes(Object[] rootNodes) { - List tmpNodes = new ArrayList(); - for (int i = 0; i < rootNodes.length; i++) { - Object obj = rootNodes[i]; - if (obj instanceof Node) { - tmpNodes.add(obj); - } else if (obj instanceof RepositoryRegister) { - RepositoryRegister repositoryRegister = (RepositoryRegister) obj; - Map repositories = repositoryRegister - .getRepositories(); - for (String name : repositories.keySet()) { - tmpNodes.add(new RepositoryNode(name, repositories - .get(name))); - } - - } - } - this.rootNodes = tmpNodes.toArray(); - } + // public void setRootNodes(Object[] rootNodes) { + // List tmpNodes = new ArrayList(); + // for (int i = 0; i < rootNodes.length; i++) { + // Object obj = rootNodes[i]; + // if (obj instanceof Node) { + // tmpNodes.add(obj); + // } else if (obj instanceof RepositoryRegister) { + // RepositoryRegister repositoryRegister = (RepositoryRegister) obj; + // Map repositories = repositoryRegister + // .getRepositories(); + // for (String name : repositories.keySet()) { + // tmpNodes.add(new RepositoryNode(name, repositories + // .get(name))); + // } + // + // } + // } + // this.rootNodes = tmpNodes.toArray(); + // } public byte[] getByteArrayFileFromId(String fileId) { InputStream fis = null; diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrUiUtils.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrUiUtils.java index b859ffdea..c7287cf85 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrUiUtils.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrUiUtils.java @@ -1,6 +1,135 @@ package org.argeo.jcr.ui.explorer.utils; +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; +import org.argeo.jcr.ui.explorer.model.WorkspaceNode; + /** Centralizes some useful methods to build Uis with JCR */ public class JcrUiUtils { + /** Insure that the UI componant is not stale, refresh if needed */ + public static void forceRefreshIfNeeded(TreeParent element) { + Node curNode; + + if (element instanceof SingleJcrNode) + curNode = ((SingleJcrNode) element).getNode(); + else if (element instanceof WorkspaceNode) + curNode = ((WorkspaceNode) element).getRootNode(); + else + return; + // TODO implement specific methods for other cases + + try { + // we mainly rely on nb of children + if (element.getChildren().length == curNode.getNodes().getSize()) + return; + else { + // get rid of children of UI object + element.clearChildren(); + element.getChildren(); + } + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexpected error while synchronising the UI with the JCR repository", + re); + } + } + /** + * Workaround to get the alias of the repository that contains the given + * element. As we cannot browse the UI tree upward we recursively browse it + * downward until we find the given element + * */ + // public static String getRepositoryAliasFromITreeElement( + // NodeContentProvider ncp, Object element) { + // RepositoryNode repositoryNode = null; + // if (element instanceof RepositoryNode) + // return ((RepositoryNode) element).getName(); + // else if (element instanceof RepositoryRegister) + // throw new ArgeoException( + // "Cannot get alias for a repository register"); + // + // // Get root elements + // Object[] elements = ncp.getElements(null); + // + // try { + // for (int i = 0; i < elements.length; i++) { + // if (elements[i] instanceof Node) { + // Node curNode = (Node) elements[i]; + // if (curNode.isNodeType(ArgeoTypes.ARGEO_USER_HOME)) { + // // Do nothing, we'll find the node in the "normal" tree + // // and + // // get corresponding alias this way round + // } else + // throw new ArgeoException( + // "Normal nodes should not be at the root of NodeTreeViewer"); + // } else if (elements[i] instanceof RepositoryRegister) { + // RepositoryRegister repositoryRegister = (RepositoryRegister) elements[i]; + // Map repositories = repositoryRegister + // .getRepositories(); + // + // for (String name : repositories.keySet()) { + // boolean found = isElementInCurrentTreePart( + // ncp, + // new RepositoryNode(name, repositories.get(name)), + // (Node) element); + // if (found) + // return name; + // } + // } else + // throw new ArgeoException( + // "Unexpected object class at the root of NodeTreeViewer"); + // } + // } catch (RepositoryException re) { + // throw new ArgeoException( + // "Unexpected error while retrieving Alias name", re); + // } + // return null; + // } + // + // /** implements the recursivity */ + // private static boolean isElementInCurrentTreePart(NodeContentProvider + // ncp, + // Object parentElement, NodParente searchedElement) { + // boolean found = false; + // if (parentElement instanceof WorkspaceNode) { + // WorkspaceNode wn = (WorkspaceNode) parentElement; + // Object[] children = wn.getChildren(); + // int i = children.length - 1; + // while (!found && i >= 0) { + // found = isElementInCurrentTreePart(ncp, children[i], + // searchedElement); + // } + // return found; + // } else if (parentElement instanceof RepositoryNode) { + // RepositoryNode rn = (RepositoryNode) parentElement; + // Object[] children = rn.getChildren(); + // int i = children.length - 1; + // while (!found && i >= 0) { + // found = isElementInCurrentTreePart(ncp, children[i], + // searchedElement); + // } + // return found; + // } else { + // Node node = (Node) parentElement; + // if (node.equals(searchedElement)) + // return true; + // NodeIterator ni; + // try { + // ni = node.getNodes(); + // while (!found && ni.hasNext()) { + // found = isElementInCurrentTreePart(ncp, ni.nextNode(), + // searchedElement); + // } + // } catch (RepositoryException e) { + // throw new ArgeoException("unexpected erreur while recursively" + // + " recovering RepositoryNode for selected object", e); + // } + // + // return found; + // } + // } } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/views/GenericJcrBrowser.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/views/GenericJcrBrowser.java index 4a2562fd0..484a2d42c 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/views/GenericJcrBrowser.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/views/GenericJcrBrowser.java @@ -15,6 +15,7 @@ import javax.jcr.observation.ObservationManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.TreeParent; import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer; import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser; @@ -25,14 +26,17 @@ import org.argeo.jcr.RepositoryRegister; import org.argeo.jcr.ui.explorer.browser.NodeContentProvider; import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider; import org.argeo.jcr.ui.explorer.browser.PropertiesContentProvider; +import org.argeo.jcr.ui.explorer.model.SingleJcrNode; import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener; import org.argeo.jcr.ui.explorer.utils.JcrFileProvider; +import org.argeo.jcr.ui.explorer.utils.JcrUiUtils; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TreeViewer; @@ -212,13 +216,13 @@ public class GenericJcrBrowser extends AbstractJcrBrowser { // nodesViewer.refresh(tmpSel.getFirstElement()); // } - private JcrFileProvider getJcrFileProvider() { - return jcrFileProvider; - } - - private FileHandler getFileHandler() { - return fileHandler; - } + // private JcrFileProvider getJcrFileProvider() { + // return jcrFileProvider; + // } + // + // private FileHandler getFileHandler() { + // return fileHandler; + // } protected TreeViewer createNodeViewer(Composite parent, final ITreeContentProvider nodeContentProvider) { @@ -236,7 +240,11 @@ public class GenericJcrBrowser extends AbstractJcrBrowser { if (!event.getSelection().isEmpty()) { IStructuredSelection sel = (IStructuredSelection) event .getSelection(); - propertiesViewer.setInput(sel.getFirstElement()); + Object firstItem = sel.getFirstElement(); + if (firstItem instanceof SingleJcrNode) + propertiesViewer + .setInput(((SingleJcrNode) firstItem) + .getNode()); } else { propertiesViewer.setInput(getViewSite()); } @@ -265,6 +273,24 @@ public class GenericJcrBrowser extends AbstractJcrBrowser { return nodesViewer; } + /** Notifies the current view that a node has been added */ + public void nodeAdded(TreeParent parentNode) { + // insure that Ui objects have been correctly created: + JcrUiUtils.forceRefreshIfNeeded(parentNode); + getNodeViewer().refresh(parentNode); + getNodeViewer().expandToLevel(parentNode, 1); + } + + /** Notifies the current view that a node has been added */ + public void nodeRemoved(TreeParent parentNode) { + IStructuredSelection newSel = new StructuredSelection(parentNode); + getNodeViewer().setSelection(newSel, true); + // Force refresh + IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer() + .getSelection(); + getNodeViewer().refresh(tmpSel.getFirstElement()); + } + class TreeObserver extends AsyncUiEventListener { public TreeObserver(Display display) { diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/resources/org/argeo/jcr/ui/explorer/messages.properties b/server/plugins/org.argeo.jcr.ui.explorer/src/main/resources/org/argeo/jcr/ui/explorer/messages.properties index b6bcd07b2..60f9f2f11 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/resources/org/argeo/jcr/ui/explorer/messages.properties +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/resources/org/argeo/jcr/ui/explorer/messages.properties @@ -1,9 +1,17 @@ ## English labels for Agreo JCR UI application ## Generic labels + +## Errors & warnings +errorUnvalidNtFolderNodeType= Error: folder can only be created on a Jcr Node +warningInvalidNodeToImport=Can only import to a node +warningInvalidMultipleSelection=This functionality is implemented only on a single node for the time being. warningUnversionableNode= Warning: Current node is not versionable. warningNoChildNode= Warning: current node has no children. +## Commands +getNodeSizeCmdLbl= Get approx. size + ## GenericNodeEditor nodeEditorLbl=Generic node editor genericNodePageTitle=Properties diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java index f62196caf..350ed4543 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java @@ -968,4 +968,37 @@ public class JcrUtils implements ArgeoJcrConstants { } return sbuf.toString(); } + + /** + * Estimate the sub tree size from current node. Computation is based on the + * Jcr {@link Property.getLength()} method. Note : it is not the exact size + * used on the disk by the current part of the JCR Tree. + */ + + public static long getNodeApproxSize(Node node) { + long curNodeSize = 0; + try { + PropertyIterator pi = node.getProperties(); + while (pi.hasNext()) { + Property prop = pi.nextProperty(); + if (prop.isMultiple()) { + int nb = prop.getLengths().length; + for (int i = 0; i < nb; i++) { + curNodeSize += (prop.getLengths()[i] > 0 ? prop + .getLengths()[i] : 0); + } + } else + curNodeSize += (prop.getLength() > 0 ? prop.getLength() : 0); + } + + NodeIterator ni = node.getNodes(); + while (ni.hasNext()) + curNodeSize += getNodeApproxSize(ni.nextNode()); + return curNodeSize; + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexpected error while recursively determining node size.", + re); + } + } }