From: Bruno Sinou Date: Tue, 20 Sep 2016 11:49:04 +0000 (+0000) Subject: Clean and refactor cms.ui.workbench bundle X-Git-Tag: argeo-commons-2.1.46~8 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=23b7a170cae60b500e9d45551f26b5075eba73a4;p=lgpl%2Fargeo-commons.git Clean and refactor cms.ui.workbench bundle git-svn-id: https://svn.argeo.org/commons/trunk@9187 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml b/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml index 802d31de6..3fdfbe3d6 100644 --- a/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml +++ b/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - @@ -12,7 +12,7 @@ - diff --git a/org.argeo.cms.ui.workbench.rap/bnd.bnd b/org.argeo.cms.ui.workbench.rap/bnd.bnd index 9f4fc9245..96534754a 100644 --- a/org.argeo.cms.ui.workbench.rap/bnd.bnd +++ b/org.argeo.cms.ui.workbench.rap/bnd.bnd @@ -4,11 +4,11 @@ Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.rap.ui,org.eclipse.core.runtime -Import-Package: org.argeo.eclipse.spring,\ -org.argeo.eclipse.ui.specific,\ -org.argeo.eclipse.ui.workbench.commands,\ -org.argeo.cms,\ +Import-Package: org.argeo.cms,\ org.argeo.cms.auth,\ -org.argeo.security.ui,\ +org.argeo.cms.ui.workbench,\ +org.argeo.cms.ui.workbench.commands,\ +org.argeo.eclipse.ui.specific,\ +org.argeo.eclipse.spring,\ org.argeo.node,\ * diff --git a/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java b/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java index 14bcee124..0ca598dce 100644 --- a/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java +++ b/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java @@ -16,7 +16,7 @@ package org.argeo.security.ui.rap; import org.argeo.cms.auth.CurrentUser; -import org.argeo.security.ui.commands.OpenHomePerspective; +import org.argeo.cms.ui.workbench.commands.OpenHomePerspective; import org.eclipse.core.commands.Category; import org.eclipse.core.commands.Command; import org.eclipse.jface.action.ICoolBarManager; diff --git a/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/commands/OpenHome.java b/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/commands/OpenHome.java index 37ebe3572..cc1bca86d 100644 --- a/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/commands/OpenHome.java +++ b/org.argeo.cms.ui.workbench.rap/src/org/argeo/security/ui/rap/commands/OpenHome.java @@ -15,9 +15,9 @@ */ package org.argeo.security.ui.rap.commands; +import org.argeo.cms.ui.workbench.UserHomePerspective; +import org.argeo.cms.ui.workbench.util.CommandUtils; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.CommandUtils; -import org.argeo.security.ui.UserHomePerspective; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; diff --git a/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml b/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml index d51c0a2e9..1c74f7a2b 100644 --- a/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml +++ b/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml @@ -5,51 +5,51 @@ http://www.springframework.org/schema/beans/spring-beans.xsd"> - - + class="org.argeo.cms.ui.workbench.internal.jcr.commands.AddRemoteRepository"> - + + class="org.argeo.cms.ui.workbench.internal.jcr.commands.RemovePrivileges"> diff --git a/org.argeo.cms.ui.workbench/META-INF/spring/common.xml b/org.argeo.cms.ui.workbench/META-INF/spring/common.xml index db613a05b..ff4304d16 100644 --- a/org.argeo.cms.ui.workbench/META-INF/spring/common.xml +++ b/org.argeo.cms.ui.workbench/META-INF/spring/common.xml @@ -4,12 +4,12 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - diff --git a/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml b/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml index 766348450..131b180de 100644 --- a/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml +++ b/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml @@ -8,22 +8,22 @@ - - - - @@ -32,16 +32,16 @@ - - diff --git a/org.argeo.cms.ui.workbench/META-INF/spring/views.xml b/org.argeo.cms.ui.workbench/META-INF/spring/views.xml index e5363dcc0..767464008 100644 --- a/org.argeo.cms.ui.workbench/META-INF/spring/views.xml +++ b/org.argeo.cms.ui.workbench/META-INF/spring/views.xml @@ -4,12 +4,12 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - - diff --git a/org.argeo.cms.ui.workbench/plugin.xml b/org.argeo.cms.ui.workbench/plugin.xml index 5b2ead753..5c77ab7d8 100644 --- a/org.argeo.cms.ui.workbench/plugin.xml +++ b/org.argeo.cms.ui.workbench/plugin.xml @@ -5,31 +5,31 @@ point="org.eclipse.ui.perspectives"> - @@ -37,7 +37,7 @@ - + @@ -104,19 +104,19 @@ name="Modules" id="org.argeo.cms.ui.workbench.modulesView" icon="icons/service_published.gif" - class="org.argeo.eclipse.ui.workbench.osgi.ModulesView"> + class="org.argeo.cms.ui.workbench.osgi.ModulesView"> + class="org.argeo.cms.ui.workbench.osgi.BundlesView"> + class="org.argeo.cms.ui.workbench.osgi.MultiplePackagesView"> @@ -238,12 +238,12 @@ --> @@ -258,22 +258,22 @@ name="Remove Privileges"> @@ -283,22 +283,22 @@ name="Open current file"> --> @@ -449,10 +449,10 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem"> + value="org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem"> @@ -470,10 +470,10 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem"> + value="org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem"> @@ -491,10 +491,10 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem"> + value="org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem"> @@ -512,7 +512,7 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.RepositoryElem"> @@ -529,9 +529,9 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem" /> + value="org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem" /> @@ -546,9 +546,9 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem" /> + value="org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem" /> @@ -563,9 +563,9 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.RepositoriesElem" /> + value="org.argeo.cms.ui.workbench.internal.jcr.model.RepositoryElem" /> @@ -578,7 +578,7 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.RemoteRepositoryElem" /> @@ -591,9 +591,9 @@ + value="org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem" /> + value="org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem" /> @@ -605,7 +605,7 @@ style="push"> - + @@ -617,7 +617,7 @@ style="push"> - + @@ -630,7 +630,7 @@ - + @@ -652,7 +652,7 @@ + provider="org.argeo.cms.ui.workbench.util.RolesSourceProvider"> @@ -677,13 +677,13 @@ + activityId="org.argeo.cms.ui.workbench.adminActivity"> + activityId="org.argeo.cms.ui.workbench.adminActivity"> - + \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java new file mode 100644 index 000000000..0b235f7e9 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Base perspective for the Jcr browser */ +public class JcrBrowserPerspective implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + IFolderLayout upperLeft = layout.createFolder( + WorkbenchUiPlugin.PLUGIN_ID + ".upperLeft", IPageLayout.LEFT, + 0.4f, layout.getEditorArea()); + upperLeft.addView(JcrBrowserView.ID); + + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java new file mode 100644 index 000000000..da9e26c0f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.useradmin.AdminLogView; +import org.argeo.cms.ui.workbench.useradmin.UserProfile; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Home perspective for the current user */ +public class MaintenancePerspective implements IPerspectiveFactory { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".adminMaintenancePerspective"; + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.50f, editorArea); + bottom.addView(AdminLogView.ID); + + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.30f, editorArea); + left.addView(UserProfile.ID); + // left.addView(RolesView.ID); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java new file mode 100644 index 000000000..5534a6126 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench; + +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** OSGi explorer perspective (to be enriched declaratively) */ +public class OsgiExplorerPerspective implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + layout.setFixed(false); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java new file mode 100644 index 000000000..f9904f2f1 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.internal.useradmin.parts.GroupsView; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UsersView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Default perspective to manage users and groups */ +public class SecurityAdminPerspective implements IPerspectiveFactory { + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.25f, editorArea); + left.addView(UsersView.ID); + left.addView(GroupsView.ID); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityUiPlugin.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityUiPlugin.java deleted file mode 100644 index 279a2b900..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityUiPlugin.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.cms.ui.workbench; - -import java.io.IOException; -import java.util.ResourceBundle; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.cms.widgets.auth.DefaultLoginDialog; -import org.eclipse.core.runtime.ILogListener; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -/** - * The activator class controls the plug-in life cycle - */ -public class SecurityUiPlugin extends AbstractUIPlugin implements ILogListener { - - private final static Log log = LogFactory.getLog(SecurityUiPlugin.class); - - private ResourceBundle messages; - - private static BundleContext bundleContext; - public static InheritableThreadLocal display = new InheritableThreadLocal() { - - @Override - protected Display initialValue() { - return Display.getCurrent(); - } - }; - - // The plug-in ID - // public final static String PLUGIN_ID = "org.argeo.security.ui"; //$NON-NLS-1$ - public final static String PLUGIN_ID = "org.argeo.cms.ui.workbench"; //$NON-NLS-1$ - - final static String CONTEXT_KEYRING = "KEYRING"; - - private CallbackHandler defaultCallbackHandler; - private ServiceRegistration defaultCallbackHandlerReg; - - // The shared instance - private static SecurityUiPlugin plugin; - - public void start(BundleContext context) throws Exception { - super.start(context); - - bundleContext = context; - - defaultCallbackHandler = new DefaultCallbackHandler(); - defaultCallbackHandlerReg = context.registerService( - CallbackHandler.class, defaultCallbackHandler, null); - - plugin = this; - messages = ResourceBundle.getBundle(PLUGIN_ID + ".messages"); - Platform.addLogListener(this); - if (log.isTraceEnabled()) - log.trace("Eclipse logging now directed to standard logging"); - - } - - public void stop(BundleContext context) throws Exception { - bundleContext = null; - defaultCallbackHandlerReg.unregister(); - } - - public static BundleContext getBundleContext() { - return bundleContext; - } - - // * Returns the shared instance - // * - // * @return the shared instance - // */ - public static SecurityUiPlugin getDefault() { - return plugin; - } - - protected class DefaultCallbackHandler implements CallbackHandler { - public void handle(final Callback[] callbacks) throws IOException, - UnsupportedCallbackException { - - // if (display != null) // RCP - Display displayToUse = display.get(); - if (displayToUse == null)// RCP - displayToUse = Display.getDefault(); - displayToUse.syncExec(new Runnable() { - public void run() { - DefaultLoginDialog dialog = new DefaultLoginDialog(display - .get().getActiveShell()); - try { - dialog.handle(callbacks); - } catch (IOException e) { - throw new CmsException("Cannot open dialog", e); - } - } - }); - // else {// RAP - // DefaultLoginDialog dialog = new DefaultLoginDialog(); - // dialog.handle(callbacks); - // } - } - - } - - public static ImageDescriptor getImageDescriptor(String path) { - return imageDescriptorFromPlugin(PLUGIN_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 this UiPlugin is not started (for JUnit tests, by instance) - */ - public static ResourceBundle getMessagesBundle() { - if (getDefault() != null) - // To avoid NPE - return getDefault().messages; - else - return null; - } - - public void logging(IStatus status, String plugin) { - Log pluginLog = LogFactory.getLog(plugin); - Integer severity = status.getSeverity(); - if (severity == IStatus.ERROR) - pluginLog.error(status.getMessage(), status.getException()); - else if (severity == IStatus.WARNING) - pluginLog.warn(status.getMessage(), status.getException()); - else if (severity == IStatus.INFO) - pluginLog.info(status.getMessage(), status.getException()); - else if (severity == IStatus.CANCEL) - if (pluginLog.isDebugEnabled()) - pluginLog.debug(status.getMessage(), status.getException()); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java new file mode 100644 index 000000000..86caad9c4 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.useradmin.LogView; +import org.argeo.cms.ui.workbench.useradmin.UserProfile; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Home perspective for the current user */ +public class UserHomePerspective implements IPerspectiveFactory { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".userHomePerspective"; + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.30f, editorArea); + left.addView(UserProfile.ID); + left.addView(LogView.ID); + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java new file mode 100644 index 000000000..18b35ae7d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench; + +import java.io.IOException; +import java.util.ResourceBundle; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.widgets.auth.DefaultLoginDialog; +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * The activator class controls the plug-in life cycle + */ +public class WorkbenchUiPlugin extends AbstractUIPlugin implements ILogListener { + + private final static Log log = LogFactory.getLog(WorkbenchUiPlugin.class); + + private ResourceBundle messages; + + private static BundleContext bundleContext; + public static InheritableThreadLocal display = new InheritableThreadLocal() { + + @Override + protected Display initialValue() { + return Display.getCurrent(); + } + }; + + // The plug-in ID + // public final static String PLUGIN_ID = "org.argeo.security.ui"; //$NON-NLS-1$ + public final static String PLUGIN_ID = "org.argeo.cms.ui.workbench"; //$NON-NLS-1$ + + final static String CONTEXT_KEYRING = "KEYRING"; + + private CallbackHandler defaultCallbackHandler; + private ServiceRegistration defaultCallbackHandlerReg; + + // The shared instance + private static WorkbenchUiPlugin plugin; + + public void start(BundleContext context) throws Exception { + super.start(context); + + bundleContext = context; + + defaultCallbackHandler = new DefaultCallbackHandler(); + defaultCallbackHandlerReg = context.registerService( + CallbackHandler.class, defaultCallbackHandler, null); + + plugin = this; + messages = ResourceBundle.getBundle(PLUGIN_ID + ".messages"); + Platform.addLogListener(this); + if (log.isTraceEnabled()) + log.trace("Eclipse logging now directed to standard logging"); + + } + + public void stop(BundleContext context) throws Exception { + bundleContext = null; + defaultCallbackHandlerReg.unregister(); + } + + public static BundleContext getBundleContext() { + return bundleContext; + } + + // * Returns the shared instance + // * + // * @return the shared instance + // */ + public static WorkbenchUiPlugin getDefault() { + return plugin; + } + + protected class DefaultCallbackHandler implements CallbackHandler { + public void handle(final Callback[] callbacks) throws IOException, + UnsupportedCallbackException { + + // if (display != null) // RCP + Display displayToUse = display.get(); + if (displayToUse == null)// RCP + displayToUse = Display.getDefault(); + displayToUse.syncExec(new Runnable() { + public void run() { + DefaultLoginDialog dialog = new DefaultLoginDialog(display + .get().getActiveShell()); + try { + dialog.handle(callbacks); + } catch (IOException e) { + throw new CmsException("Cannot open dialog", e); + } + } + }); + // else {// RAP + // DefaultLoginDialog dialog = new DefaultLoginDialog(); + // dialog.handle(callbacks); + // } + } + + } + + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_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 this UiPlugin is not started (for JUnit tests, by instance) + */ + public static ResourceBundle getMessagesBundle() { + if (getDefault() != null) + // To avoid NPE + return getDefault().messages; + else + return null; + } + + public void logging(IStatus status, String plugin) { + Log pluginLog = LogFactory.getLog(plugin); + Integer severity = status.getSeverity(); + if (severity == IStatus.ERROR) + pluginLog.error(status.getMessage(), status.getException()); + else if (severity == IStatus.WARNING) + pluginLog.warn(status.getMessage(), status.getException()); + else if (severity == IStatus.INFO) + pluginLog.info(status.getMessage(), status.getException()); + else if (severity == IStatus.CANCEL) + if (pluginLog.isDebugEnabled()) + pluginLog.debug(status.getMessage(), status.getException()); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java new file mode 100644 index 000000000..c8a107627 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java @@ -0,0 +1,15 @@ +package org.argeo.cms.ui.workbench.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** Utilitary command to enable sub menus in various toolbars. Does nothing */ +public class DoNothing extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".doNothing"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java new file mode 100644 index 000000000..d48291f38 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.commands; + +import static org.argeo.cms.CmsMsg.changePassword; +import static org.argeo.cms.CmsMsg.currentPassword; +import static org.argeo.cms.CmsMsg.newPassword; +import static org.argeo.cms.CmsMsg.passwordChanged; +import static org.argeo.cms.CmsMsg.repeatNewPassword; +import static org.eclipse.jface.dialogs.IMessageProvider.INFORMATION; + +import java.security.AccessController; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Opens the change password dialog. */ +public class OpenChangePasswordDialog extends AbstractHandler { + private final static Log log = LogFactory + .getLog(OpenChangePasswordDialog.class); + private UserAdmin userAdmin; + private UserTransaction userTransaction; + + public Object execute(ExecutionEvent event) throws ExecutionException { + ChangePasswordDialog dialog = new ChangePasswordDialog( + HandlerUtil.getActiveShell(event), userAdmin); + if (dialog.open() == Dialog.OK) { + MessageDialog.openInformation(HandlerUtil.getActiveShell(event), + passwordChanged.lead(), passwordChanged.lead()); + } + return null; + } + + @SuppressWarnings("unchecked") + protected void changePassword(char[] oldPassword, char[] newPassword) { + Subject subject = Subject.getSubject(AccessController.getContext()); + String name = subject.getPrincipals(X500Principal.class).iterator() + .next().toString(); + LdapName dn; + try { + dn = new LdapName(name); + } catch (InvalidNameException e) { + throw new CmsException("Invalid user dn " + name, e); + } + User user = (User) userAdmin.getRole(dn.toString()); + if (!user.hasCredential(null, oldPassword)) + throw new CmsException("Invalid password"); + if (newPassword.equals("")) + throw new CmsException("New password empty"); + try { + userTransaction.begin(); + user.getCredentials().put(null, newPassword); + userTransaction.commit(); + } catch (Exception e) { + try { + userTransaction.rollback(); + } catch (Exception e1) { + log.error("Could not roll back", e1); + } + if (e instanceof RuntimeException) + throw (RuntimeException) e; + else + throw new CmsException("Cannot change password", e); + } + } + + public void setUserAdmin(UserAdmin userDetailsManager) { + this.userAdmin = userDetailsManager; + } + + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } + + class ChangePasswordDialog extends TitleAreaDialog { + private static final long serialVersionUID = -6963970583882720962L; + private Text oldPassword, newPassword1, newPassword2; + + public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) { + super(parentShell); + } + + protected Point getInitialSize() { + return new Point(400, 450); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + true)); + Composite composite = new Composite(dialogarea, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false)); + oldPassword = createLP(composite, currentPassword.lead()); + newPassword1 = createLP(composite, newPassword.lead()); + newPassword2 = createLP(composite, repeatNewPassword.lead()); + + setMessage(changePassword.lead(), INFORMATION); + parent.pack(); + return composite; + } + + @Override + protected void okPressed() { + try { + if (!newPassword1.getText().equals(newPassword2.getText())) + throw new CmsException("New passwords are different"); + changePassword(oldPassword.getTextChars(), + newPassword1.getTextChars()); + close(); + } catch (Exception e) { + ErrorFeedback.show("Cannot change password", e); + } + } + + /** Creates label and password. */ + protected Text createLP(Composite parent, String label) { + new Label(parent, SWT.NONE).setText(label); + Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD + | SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + return text; + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(changePassword.lead()); + } + + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java new file mode 100644 index 000000000..ecf84c351 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.commands; + +import javax.jcr.Node; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.JcrQueryEditorInput; +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodeEditorInput; +import org.argeo.cms.ui.workbench.jcr.DefaultNodeEditor; +import org.argeo.cms.ui.workbench.jcr.GenericJcrQueryEditor; +import org.argeo.eclipse.ui.EclipseUiException; +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.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Open a {@link Node} editor of a specific type given the node path */ +public class OpenEditor extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".openEditor"; + + public final static String PARAM_PATH = "param.jcrNodePath"; + public final static String PARAM_EDITOR_ID = "param.editorId"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + String editorId = event.getParameter(PARAM_EDITOR_ID); + try { + IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow( + event).getActivePage(); + if (DefaultNodeEditor.ID.equals(editorId)) { + String path = event.getParameter(PARAM_PATH); + NodeEditorInput nei = new NodeEditorInput(path); + activePage.openEditor(nei, DefaultNodeEditor.ID); + } else if (GenericJcrQueryEditor.ID.equals(editorId)) { + JcrQueryEditorInput editorInput = new JcrQueryEditorInput( + GenericJcrQueryEditor.ID, null); + activePage.openEditor(editorInput, editorId); + } + } catch (PartInitException e) { + throw new EclipseUiException( + "Cannot open editor of ID " + editorId, e); + } + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenFile.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenFile.java new file mode 100644 index 000000000..75a90cd6a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenFile.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.specific.OpenFileService; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** + * RWT specific command handler to open a file retrieved from the server. It + * forwards the request to the correct service after encoding file name and path + * in the request URI. + * + *

+ * The parameter "URI" is used to determine the correct file service, the path + * and the file name. An optional file name can be precized to present a + * different file name as the one used to retrieve it to the end user. + *

+ * + *

+ * Various instances of this handler with different command ID might coexist in + * order to provide context specific download service. + *

+ * + *

+ * The instance specific service is called by its ID and must have been + * externally created + *

+ */ +public class OpenFile extends AbstractHandler { + // private final static Log log = LogFactory.getLog(OpenFile.class); + + /* DEPENDENCY INJECTION */ + private String openFileServiceId; + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".openFile"; + public final static String PARAM_FILE_NAME = OpenFileService.PARAM_FILE_NAME; + public final static String PARAM_FILE_URI = OpenFileService.PARAM_FILE_URI; // "param.fileURI"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + String fileName = event.getParameter(PARAM_FILE_NAME); + String fileUri = event.getParameter(PARAM_FILE_URI); + // Sanity check + if (fileUri == null || "".equals(fileUri.trim()) + || openFileServiceId == null + || "".equals(openFileServiceId.trim())) + return null; + + org.argeo.eclipse.ui.specific.OpenFile openFileClient = new org.argeo.eclipse.ui.specific.OpenFile(); + openFileClient.execute(openFileServiceId, fileUri, fileName); + + return null; + } + + /* DEPENDENCY INJECTION */ + public void setOpenFileServiceId(String openFileServiceId) { + this.openFileServiceId = openFileServiceId; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java new file mode 100644 index 000000000..0e1983234 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.commands; + +import org.argeo.cms.ui.workbench.UserHomePerspective; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Default action of the user menu */ +public class OpenHomePerspective extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + HandlerUtil.getActiveSite(event).getWorkbenchWindow() + .openPage(UserHomePerspective.ID, null); + } catch (WorkbenchException e) { + ErrorFeedback.show("Cannot open home perspective", e); + } + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java new file mode 100644 index 000000000..43cf1074d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal; + +/** Constants used across the application. */ +public interface WorkbenchConstants { + /* + * MISCEALLENEOUS + */ + public final static String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm"; + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/FullVersioningTreeContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/FullVersioningTreeContentProvider.java new file mode 100644 index 000000000..148605ba4 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/FullVersioningTreeContentProvider.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; +import javax.jcr.version.Version; +import javax.jcr.version.VersionHistory; +import javax.jcr.version.VersionIterator; +import javax.jcr.version.VersionManager; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Display some version information of a JCR full versionable node in a tree + * like structure + */ +public class FullVersioningTreeContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = 8691772509491211112L; + + /** + * Sends back the first level of the Tree. input element must be a single + * node object + */ + public Object[] getElements(Object inputElement) { + try { + Node rootNode = (Node) inputElement; + String curPath = rootNode.getPath(); + VersionManager vm = rootNode.getSession().getWorkspace() + .getVersionManager(); + + VersionHistory vh = vm.getVersionHistory(curPath); + List result = new ArrayList(); + VersionIterator vi = vh.getAllLinearVersions(); + + while (vi.hasNext()) { + result.add(vi.nextVersion()); + } + return result.toArray(); + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while getting version elements", re); + } + } + + public Object[] getChildren(Object parentElement) { + try { + if (parentElement instanceof Version) { + List tmp = new ArrayList(); + tmp.add(((Version) parentElement).getFrozenNode()); + return tmp.toArray(); + } + } catch (RepositoryException re) { + throw new EclipseUiException("Unexpected error while getting child " + + "node for version element", re); + } + return null; + } + + public Object getParent(Object element) { + try { + // this will not work in a simpleVersionning environment, parent is + // not a node. + if (element instanceof Node + && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) { + Node node = (Node) element; + return node.getParent(); + } else + return null; + } catch (RepositoryException e) { + return null; + } + } + + public boolean hasChildren(Object element) { + try { + if (element instanceof Version) + return true; + else if (element instanceof Node) + return ((Node) element).hasNodes(); + else + return false; + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot check children of " + element, e); + } + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/GenericNodeDoubleClickListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/GenericNodeDoubleClickListener.java new file mode 100644 index 000000000..4ec44df2c --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/GenericNodeDoubleClickListener.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoryElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericNodeEditorInput; +import org.argeo.cms.ui.workbench.jcr.DefaultNodeEditor; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.ui.PartInitException; + +/** Centralizes the management of double click on a NodeTreeViewer */ +public class GenericNodeDoubleClickListener implements IDoubleClickListener { + // private final static Log log = LogFactory + // .getLog(GenericNodeDoubleClickListener.class); + + private TreeViewer nodeViewer; + + // private JcrFileProvider jfp; + // private FileHandler fileHandler; + + public GenericNodeDoubleClickListener(TreeViewer nodeViewer) { + this.nodeViewer = nodeViewer; + // jfp = new JcrFileProvider(); + // Commented out. see https://www.argeo.org/bugzilla/show_bug.cgi?id=188 + // fileHandler = null; + // fileHandler = new FileHandler(jfp); + } + + public void doubleClick(DoubleClickEvent event) { + if (event.getSelection() == null || event.getSelection().isEmpty()) + return; + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (obj instanceof RepositoryElem) { + RepositoryElem rpNode = (RepositoryElem) obj; + if (!rpNode.isConnected()) { + rpNode.login(); + nodeViewer.refresh(obj); + } + } else if (obj instanceof WorkspaceElem) { + WorkspaceElem wn = (WorkspaceElem) obj; + if (wn.isConnected()) + wn.logout(); + else + wn.login(); + nodeViewer.refresh(obj); + } else if (obj instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj; + Node node = sjn.getNode(); + try { + if (node.isNodeType(NodeType.NT_FILE)) { + // double click on a file node triggers its opening + // String name = node.getName(); + // String id = node.getIdentifier(); + + // TODO add integration of direct retrieval of the binary in + // a JCR repo. + // Map params = new HashMap(); + // params.put(OpenFile.PARAM_FILE_NAME, name); + // params.put(OpenFile.PARAM_FILE_URI, "jcr://" + id); + // CommandUtils + // .callCommand("org.argeo.security.ui.specific.openFile", + // params); + + // For the file provider to be able to browse the + // various + // repository. + // TODO : enhanced that. + // ITreeContentProvider itcp = (ITreeContentProvider) + // nodeViewer + // .getContentProvider(); + // jfp.setReferenceNode(node); + // if (fileHandler != null) + // fileHandler.openFile(name, id); + } + GenericNodeEditorInput gnei = new GenericNodeEditorInput(node); + WorkbenchUiPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .openEditor(gnei, DefaultNodeEditor.ID); + } catch (RepositoryException re) { + throw new EclipseUiException( + "Repository error while getting node info", re); + } catch (PartInitException pie) { + throw new EclipseUiException( + "Unexepected exception while opening node editor", pie); + } + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/JcrBrowserUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/JcrBrowserUtils.java new file mode 100644 index 000000000..363ecfbb5 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/JcrBrowserUtils.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoriesElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoryElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; + +/** Centralizes useful methods to manage the JCR Browser */ +public class JcrBrowserUtils { + + /** Insure that the UI component is not stale, refresh if needed */ + public static void forceRefreshIfNeeded(TreeParent element) { + Node curNode = null; + + boolean doRefresh = false; + + try { + if (element instanceof SingleJcrNodeElem) { + curNode = ((SingleJcrNodeElem) element).getNode(); + } else if (element instanceof WorkspaceElem) { + curNode = ((WorkspaceElem) element).getRootNode(); + } + + if (curNode != null + && element.getChildren().length != curNode.getNodes() + .getSize()) + doRefresh = true; + else if (element instanceof RepositoryElem) { + RepositoryElem rn = (RepositoryElem) element; + if (rn.isConnected()) { + String[] wkpNames = rn.getAccessibleWorkspaceNames(); + if (element.getChildren().length != wkpNames.length) + doRefresh = true; + } + } else if (element instanceof RepositoriesElem) { + doRefresh = true; + // Always force refresh for RepositoriesElem : the condition + // below does not take remote repository into account and it is + // not trivial to do so. + + // RepositoriesElem rn = (RepositoriesElem) element; + // if (element.getChildren().length != + // rn.getRepositoryRegister() + // .getRepositories().size()) + // doRefresh = true; + } + if (doRefresh) { + element.clearChildren(); + element.getChildren(); + } + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while synchronising the UI with the JCR repository", + re); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/NodeContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/NodeContentProvider.java new file mode 100644 index 000000000..6b2bbfd28 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/NodeContentProvider.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoriesElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.jcr.RepositoryRegister; +import org.argeo.node.NodeConstants; +import org.argeo.node.NodeUtils; +import org.argeo.node.security.Keyring; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Implementation of the {@code ITreeContentProvider} to display multiple + * repository environment in a tree like structure + */ +public class NodeContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = -4083809398848374403L; + final private RepositoryRegister repositoryRegister; + final private RepositoryFactory repositoryFactory; + + // Current user session on the default workspace of the argeo Node + final private Session userSession; + final private Keyring keyring; + private boolean sortChildren; + + // Reference for cleaning + private SingleJcrNodeElem homeNode = null; + private RepositoriesElem repositoriesNode = null; + + // Utils + private TreeBrowserComparator itemComparator = new TreeBrowserComparator(); + + public NodeContentProvider(Session userSession, Keyring keyring, + RepositoryRegister repositoryRegister, + RepositoryFactory repositoryFactory, Boolean sortChildren) { + this.userSession = userSession; + this.keyring = keyring; + this.repositoryRegister = repositoryRegister; + this.repositoryFactory = repositoryFactory; + this.sortChildren = sortChildren; + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput == null)// dispose + return; + + if (userSession != null) { + Node userHome = NodeUtils.getUserHome(userSession); + if (userHome != null) { + // TODO : find a way to dynamically get alias for the node + if (homeNode != null) + homeNode.dispose(); + homeNode = new SingleJcrNodeElem(null, userHome, + userSession.getUserID(), NodeConstants.ALIAS_NODE); + } + } + if (repositoryRegister != null) { + if (repositoriesNode != null) + repositoriesNode.dispose(); + repositoriesNode = new RepositoriesElem("Repositories", + repositoryRegister, repositoryFactory, null, userSession, + keyring); + } + } + + /** + * Sends back the first level of the Tree. Independent from inputElement + * that can be null + */ + public Object[] getElements(Object inputElement) { + List objs = new ArrayList(); + if (homeNode != null) + objs.add(homeNode); + if (repositoriesNode != null) + objs.add(repositoriesNode); + return objs.toArray(); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof TreeParent) { + if (sortChildren) { + Object[] tmpArr = ((TreeParent) parentElement).getChildren(); + if (tmpArr == null) + return new Object[0]; + TreeParent[] arr = new TreeParent[tmpArr.length]; + for (int i = 0; i < tmpArr.length; i++) + arr[i] = (TreeParent) tmpArr[i]; + Arrays.sort(arr, itemComparator); + return arr; + } else + return ((TreeParent) parentElement).getChildren(); + } else + return new Object[0]; + } + + /** + * Sets whether the content provider should order the children nodes or not. + * It is user duty to call a full refresh of the tree after changing this + * parameter. + */ + public void setSortChildren(boolean sortChildren) { + this.sortChildren = sortChildren; + } + + public Object getParent(Object element) { + if (element instanceof TreeParent) { + return ((TreeParent) element).getParent(); + } else + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof RepositoriesElem) { + RepositoryRegister rr = ((RepositoriesElem) element) + .getRepositoryRegister(); + return rr.getRepositories().size() > 0; + } else if (element instanceof TreeParent) { + TreeParent tp = (TreeParent) element; + return tp.hasChildren(); + } + return false; + } + + public void dispose() { + if (homeNode != null) + homeNode.dispose(); + if (repositoriesNode != null) { + // logs out open sessions + // see https://bugzilla.argeo.org/show_bug.cgi?id=23 + repositoriesNode.dispose(); + } + } + + /** + * Specific comparator for this view. See specification here: + * https://www.argeo.org/bugzilla/show_bug.cgi?id=139 + */ + private class TreeBrowserComparator implements Comparator { + + public int category(TreeParent element) { + if (element instanceof SingleJcrNodeElem) { + Node node = ((SingleJcrNodeElem) element).getNode(); + try { + if (node.isNodeType(NodeType.NT_FOLDER)) + return 5; + } catch (RepositoryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return 10; + } + + public int compare(TreeParent o1, TreeParent o2) { + int cat1 = category(o1); + int cat2 = category(o2); + + if (cat1 != cat2) { + return cat1 - cat2; + } + return o1.getName().compareTo(o2.getName()); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/NodeLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/NodeLabelProvider.java new file mode 100644 index 000000000..df8a26e7a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/NodeLabelProvider.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.ui.workbench.internal.jcr.model.RemoteRepositoryElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoriesElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoryElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.jcr.JcrImages; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.node.ArgeoTypes; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Image; + +/** Provides reasonable defaults for know JCR types. */ +public class NodeLabelProvider extends ColumnLabelProvider { + private static final long serialVersionUID = -3662051696443321843L; + + private final static Log log = LogFactory.getLog(NodeLabelProvider.class); + + public String getText(Object element) { + try { + if (element instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; + return getText(sjn.getNode()); + } else if (element instanceof Node) { + return getText((Node) element); + } else + return super.getText(element); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected JCR error while getting node name."); + } + } + + protected String getText(Node node) throws RepositoryException { + String label = node.getName(); + StringBuffer mixins = new StringBuffer(""); + for (NodeType type : node.getMixinNodeTypes()) + mixins.append(' ').append(type.getName()); + + return label + " [" + node.getPrimaryNodeType().getName() + mixins + + "]"; + } + + @Override + public Image getImage(Object element) { + if (element instanceof RemoteRepositoryElem) { + if (((RemoteRepositoryElem) element).isConnected()) + return JcrImages.REMOTE_CONNECTED; + else + return JcrImages.REMOTE_DISCONNECTED; + } else if (element instanceof RepositoryElem) { + if (((RepositoryElem) element).isConnected()) + return JcrImages.REPOSITORY_CONNECTED; + else + return JcrImages.REPOSITORY_DISCONNECTED; + } else if (element instanceof WorkspaceElem) { + if (((WorkspaceElem) element).isConnected()) + return JcrImages.WORKSPACE_CONNECTED; + else + return JcrImages.WORKSPACE_DISCONNECTED; + } else if (element instanceof RepositoriesElem) { + return JcrImages.REPOSITORIES; + } else if (element instanceof SingleJcrNodeElem) { + Node nodeElem = ((SingleJcrNodeElem) element).getNode(); + return getImage(nodeElem); + + // if (element instanceof Node) { + // return getImage((Node) element); + // } else if (element instanceof WrappedNode) { + // return getImage(((WrappedNode) element).getNode()); + // } else if (element instanceof NodesWrapper) { + // return getImage(((NodesWrapper) element).getNode()); + // } + } + // try { + // return super.getImage(); + // } catch (RepositoryException e) { + // return null; + // } + return super.getImage(element); + } + + protected Image getImage(Node node) { + try { + if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)) + return JcrImages.FILE; + else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER)) + return JcrImages.FOLDER; + else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_RESOURCE)) + return JcrImages.BINARY; + else if (node.isNodeType(ArgeoTypes.ARGEO_USER_HOME)) + return JcrImages.HOME; + else + return JcrImages.NODE; + } catch (RepositoryException e) { + log.warn("Error while retrieving type for " + node + + " in order to display corresponding image"); + e.printStackTrace(); + return null; + } + + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/PropertiesContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/PropertiesContentProvider.java new file mode 100644 index 000000000..f26f80948 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/PropertiesContentProvider.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import java.util.Set; +import java.util.TreeSet; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class PropertiesContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = 5227554668841613078L; + private JcrItemsComparator itemComparator = new JcrItemsComparator(); + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getElements(Object inputElement) { + try { + if (inputElement instanceof Node) { + Set props = new TreeSet(itemComparator); + PropertyIterator pit = ((Node) inputElement).getProperties(); + while (pit.hasNext()) + props.add(pit.nextProperty()); + return props.toArray(); + } + return new Object[] {}; + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot get element for " + inputElement, + e); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/PropertyLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/PropertyLabelProvider.java new file mode 100644 index 000000000..3014bb6a6 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/PropertyLabelProvider.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Value; + +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ViewerCell; + +/** Default basic label provider for a given JCR Node's properties */ +public class PropertyLabelProvider extends ColumnLabelProvider implements + WorkbenchConstants { + private static final long serialVersionUID = -5405794508731390147L; + + // To be able to change column order easily + public static final int COLUMN_PROPERTY = 0; + public static final int COLUMN_VALUE = 1; + public static final int COLUMN_ATTRIBUTES = 2; + + // Utils + protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT); + + public void update(ViewerCell cell) { + Object element = cell.getElement(); + cell.setText(getColumnText(element, cell.getColumnIndex())); + } + + public String getColumnText(Object element, int columnIndex) { + try { + if (element instanceof Property) { + Property prop = (Property) element; + if (prop.isMultiple()) { + switch (columnIndex) { + case COLUMN_PROPERTY: + return prop.getName(); + case COLUMN_VALUE: + // Corresponding values are listed on children + return ""; + case COLUMN_ATTRIBUTES: + return JcrUtils.getPropertyDefinitionAsString(prop); + } + } else { + switch (columnIndex) { + case COLUMN_PROPERTY: + return prop.getName(); + case COLUMN_VALUE: + return formatValueAsString(prop.getValue()); + case COLUMN_ATTRIBUTES: + return JcrUtils.getPropertyDefinitionAsString(prop); + } + } + } else if (element instanceof Value) { + Value val = (Value) element; + + switch (columnIndex) { + case COLUMN_PROPERTY: + // Nothing to show + return ""; + case COLUMN_VALUE: + return formatValueAsString(val); + case COLUMN_ATTRIBUTES: + // Corresponding attributes are listed on the parent + return ""; + } + } + + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexepected error while getting property values", re); + } + return null; + } + + private String formatValueAsString(Value value) { + // TODO enhance this method + try { + String strValue; + + if (value.getType() == PropertyType.BINARY) + strValue = ""; + else if (value.getType() == PropertyType.DATE) + strValue = timeFormatter.format(value.getDate().getTime()); + else + strValue = value.getString(); + return strValue; + } catch (RepositoryException e) { + throw new EclipseUiException("unexpected error while formatting value", + e); + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/SingleNodeAsTreeContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/SingleNodeAsTreeContentProvider.java new file mode 100644 index 000000000..558e35f40 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/SingleNodeAsTreeContentProvider.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Implementation of the {@code ITreeContentProvider} in order to display a + * single JCR node and its children in a tree like structure + */ +public class SingleNodeAsTreeContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = -2128326504754297297L; + // private Node rootNode; + private JcrItemsComparator itemComparator = new JcrItemsComparator(); + + /** + * Sends back the first level of the Tree. input element must be a single + * node object + */ + public Object[] getElements(Object inputElement) { + try { + Node rootNode = (Node) inputElement; + List result = new ArrayList(); + NodeIterator ni = rootNode.getNodes(); + while (ni.hasNext()) { + result.add(ni.nextNode()); + } + + return result.toArray(); + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while getting child nodes for children editor page ", + re); + } + } + + public Object[] getChildren(Object parentElement) { + return childrenNodes((Node) parentElement); + } + + public Object getParent(Object element) { + try { + Node node = (Node) element; + if (!node.getPath().equals("/")) + return node.getParent(); + else + return null; + } catch (RepositoryException e) { + return null; + } + } + + public boolean hasChildren(Object element) { + try { + return ((Node) element).hasNodes(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot check children of " + element, e); + } + } + + public void dispose() { + } + + 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 EclipseUiException("Cannot list children of " + parentNode, e); + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/VersionLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/VersionLabelProvider.java new file mode 100644 index 000000000..b33af515a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/VersionLabelProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.version.Version; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.viewers.ColumnLabelProvider; + +/** + * Simple wrapping of the ColumnLabelProvider class to provide text display in + * order to build a tree for version. The getText() method does not assume that + * {@link Version} extends {@link Node} class to respect JCR 2.0 specification + * + */ +public class VersionLabelProvider extends ColumnLabelProvider { + private static final long serialVersionUID = 5270739851193688238L; + + public String getText(Object element) { + try { + if (element instanceof Version) { + Version version = (Version) element; + return version.getName(); + } else if (element instanceof Node) { + return ((Node) element).getName(); + } + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while getting element name", re); + } + return super.getText(element); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java new file mode 100644 index 000000000..87bf557ad --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.eclipse.ui.dialogs.SingleValue; +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, only on {@link SingleJcrNodeElem} and + * {@link WorkspaceElem} TreeObject types. + * + * This handler assumes that a selection provider is available and picks only + * first selected item. It is UI's job to enable the command only when the + * selection contains one and only one element. Thus no parameter is passed + * through the command. + */ +public class AddFolderNode extends AbstractHandler { + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".addFolderNode"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + TreeParent treeParentNode = null; + Node jcrParentNode = null; + + if (obj instanceof SingleJcrNodeElem) { + treeParentNode = (TreeParent) obj; + jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode(); + } else if (obj instanceof WorkspaceElem) { + treeParentNode = (TreeParent) obj; + jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode(); + } else + return null; + + String folderName = SingleValue.ask("Folder name", + "Enter folder name"); + if (folderName != null) { + try { + jcrParentNode.addNode(folderName, NodeType.NT_FOLDER); + jcrParentNode.getSession().save(); + view.nodeAdded(treeParentNode); + } catch (RepositoryException e) { + ErrorFeedback.show("Cannot create folder " + folderName + + " under " + treeParentNode, e); + } + } + } else { + ErrorFeedback.show(WorkbenchUiPlugin + .getMessage("errorUnvalidNtFolderNodeType")); + } + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java new file mode 100644 index 000000000..d501a6408 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.internal.jcr.parts.AddPrivilegeWizard; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +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.jface.wizard.WizardDialog; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.UserAdmin; + +/** Open a dialog to add privileges on the selected node to a chosen group */ +public class AddPrivileges extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".addPrivileges"; + + /* DEPENDENCY INJECTION */ + private UserAdmin userAdmin; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + TreeParent treeParentNode = null; + Node jcrParentNode = null; + + if (obj instanceof SingleJcrNodeElem) { + treeParentNode = (TreeParent) obj; + jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode(); + } else if (obj instanceof WorkspaceElem) { + treeParentNode = (TreeParent) obj; + jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode(); + } else + return null; + + try { + String targetPath = jcrParentNode.getPath(); + AddPrivilegeWizard wizard = new AddPrivilegeWizard( + jcrParentNode.getSession(), targetPath, userAdmin); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + dialog.open(); + return null; + } catch (RepositoryException re) { + throw new EclipseUiException("Unable to retrieve " + + "path or JCR session to add privilege on " + + jcrParentNode, re); + } + } else { + ErrorFeedback.show("Cannot add privileges"); + } + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java new file mode 100644 index 000000000..c8a8738a2 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.net.URI; +import java.util.Hashtable; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +import org.argeo.node.ArgeoNames; +import org.argeo.node.ArgeoTypes; +import org.argeo.node.NodeConstants; +import org.argeo.node.NodeUtils; +import org.argeo.node.security.Keyring; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +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.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Connect to a remote repository and, if successful publish it as an OSGi + * service. + */ +public class AddRemoteRepository extends AbstractHandler implements + WorkbenchConstants, ArgeoNames { + + private RepositoryFactory repositoryFactory; + private Repository nodeRepository; + private Keyring keyring; + + public Object execute(ExecutionEvent event) throws ExecutionException { + RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog( + Display.getDefault().getActiveShell()); + if (dlg.open() == Dialog.OK) { + CommandUtils.callCommand(Refresh.ID); + } + return null; + } + + public void setRepositoryFactory(RepositoryFactory repositoryFactory) { + this.repositoryFactory = repositoryFactory; + } + + public void setKeyring(Keyring keyring) { + this.keyring = keyring; + } + + public void setNodeRepository(Repository nodeRepository) { + this.nodeRepository = nodeRepository; + } + + class RemoteRepositoryLoginDialog extends TitleAreaDialog { + private static final long serialVersionUID = 2234006887750103399L; + private Text name; + private Text uri; + private Text username; + private Text password; + private Button saveInKeyring; + + public RemoteRepositoryLoginDialog(Shell parentShell) { + super(parentShell); + } + + protected Point getInitialSize() { + return new Point(600, 400); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + true)); + Composite composite = new Composite(dialogarea, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false)); + setMessage("Login to remote repository", IMessageProvider.NONE); + name = createLT(composite, "Name", "remoteRepository"); + uri = createLT(composite, "URI", + "http://localhost:7070/data/jcr/node"); + username = createLT(composite, "User", ""); + password = createLP(composite, "Password"); + + saveInKeyring = createLC(composite, "Remember password", false); + parent.pack(); + return composite; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + Button test = createButton(parent, 2, "Test", false); + test.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -1829962269440419560L; + + public void widgetSelected(SelectionEvent arg0) { + testConnection(); + } + }); + } + + void testConnection() { + Session session = null; + try { + URI checkedUri = new URI(uri.getText()); + String checkedUriStr = checkedUri.toString(); + + Hashtable params = new Hashtable(); + params.put(NodeConstants.JCR_REPOSITORY_URI, checkedUriStr); + Repository repository = repositoryFactory.getRepository(params); + if (username.getText().trim().equals("")) {// anonymous + session = repository.login(); + } else { + // FIXME use getTextChars() when upgrading to 3.7 + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412 + char[] pwd = password.getText().toCharArray(); + SimpleCredentials sc = new SimpleCredentials( + username.getText(), pwd); + session = repository.login(sc, "main"); + MessageDialog.openInformation(getParentShell(), "Success", + "Connection to '" + uri.getText() + "' successful"); + } + } catch (Exception e) { + ErrorFeedback.show( + "Connection test failed for " + uri.getText(), e); + } finally { + JcrUtils.logoutQuietly(session); + } + } + + @Override + protected void okPressed() { + Session nodeSession = null; + try { + nodeSession = nodeRepository.login(); + Node home = NodeUtils.getUserHome(nodeSession); + + Node remote = home.hasNode(ARGEO_REMOTE) ? home + .getNode(ARGEO_REMOTE) : home.addNode(ARGEO_REMOTE); + if (remote.hasNode(name.getText())) + throw new EclipseUiException( + "There is already a remote repository named " + + name.getText()); + Node remoteRepository = remote.addNode(name.getText(), + ArgeoTypes.ARGEO_REMOTE_REPOSITORY); + remoteRepository.setProperty(ARGEO_URI, uri.getText()); + remoteRepository.setProperty(ARGEO_USER_ID, username.getText()); + nodeSession.save(); + if (saveInKeyring.getSelection()) { + String pwdPath = remoteRepository.getPath() + '/' + + ARGEO_PASSWORD; + keyring.set(pwdPath, password.getText().toCharArray()); + } + nodeSession.save(); + MessageDialog.openInformation( + getParentShell(), + "Repository Added", + "Remote repository '" + username.getText() + "@" + + uri.getText() + "' added"); + + super.okPressed(); + } catch (Exception e) { + ErrorFeedback.show("Cannot add remote repository", e); + } finally { + JcrUtils.logoutQuietly(nodeSession); + } + } + + /** Creates label and text. */ + protected Text createLT(Composite parent, String label, String initial) { + new Label(parent, SWT.NONE).setText(label); + Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + text.setText(initial); + return text; + } + + /** Creates label and check. */ + protected Button createLC(Composite parent, String label, + Boolean initial) { + new Label(parent, SWT.NONE).setText(label); + Button check = new Button(parent, SWT.CHECK); + check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + check.setSelection(initial); + return check; + } + + protected Text createLP(Composite parent, String label) { + new Label(parent, SWT.NONE).setText(label); + Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER + | SWT.PASSWORD); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return text; + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java new file mode 100644 index 000000000..ccccb8ecd --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.util.Arrays; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.RepositoryElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.eclipse.ui.dialogs.SingleValue; +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; + +/** Create a new JCR workspace */ +public class CreateWorkspace extends AbstractHandler { + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".addFolderNode"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (!(obj instanceof RepositoryElem)) + return null; + + RepositoryElem repositoryNode = (RepositoryElem) obj; + String workspaceName = SingleValue.ask("Workspace name", + "Enter workspace name"); + if (workspaceName != null) { + if (Arrays.asList(repositoryNode.getAccessibleWorkspaceNames()) + .contains(workspaceName)) { + ErrorFeedback.show("Workspace " + workspaceName + + " already exists."); + } else { + repositoryNode.createWorkspace(workspaceName); + view.nodeAdded(repositoryNode); + } + } + } else { + ErrorFeedback.show("Cannot create workspace"); + } + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java new file mode 100644 index 000000000..219d854b5 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.util.Iterator; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +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.ui.handlers.HandlerUtil; + +/** + * Delete 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. + * + * This handler is still 'hard linked' to a GenericJcrBrowser view to enable + * correct tree refresh when a node is added. This must be corrected in future + * versions. + */ +public class DeleteNodes extends AbstractHandler { + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + // confirmation + StringBuffer buf = new StringBuffer(""); + Iterator lst = ((IStructuredSelection) selection).iterator(); + while (lst.hasNext()) { + SingleJcrNodeElem sjn = ((SingleJcrNodeElem) lst.next()); + buf.append(sjn.getName()).append(' '); + } + Boolean ok = MessageDialog.openConfirm( + HandlerUtil.getActiveShell(event), "Confirm deletion", + "Do you want to delete " + buf + "?"); + + // operation + if (ok) { + Iterator it = ((IStructuredSelection) selection).iterator(); + Object obj = null; + SingleJcrNodeElem ancestor = null; + WorkspaceElem rootAncestor = null; + try { + while (it.hasNext()) { + obj = it.next(); + if (obj instanceof SingleJcrNodeElem) { + // Cache objects + SingleJcrNodeElem sjn = (SingleJcrNodeElem) 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 WorkspaceElem) + rootAncestor = (WorkspaceElem) tp; + else + ancestor = getOlder(ancestor, (SingleJcrNodeElem) 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 SingleJcrNodeElem getOlder(SingleJcrNodeElem A, SingleJcrNodeElem 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 EclipseUiException("Cannot find ancestor", re); + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java new file mode 100644 index 000000000..2414f042b --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.commands.OpenFile; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +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; + +/** + * Canonically call JCR {@link Session#exportSystemView()} on the first element + * returned by {@link HandlerUtil#getActiveWorkbenchWindow()} + * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}, + * with both skipBinary & noRecurse boolean flags set to false. + * + * Resulting stream is saved in a tmp file and opened via the {@link OpenFile} + * single-sourced command. + */ +public class DumpNode extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".dumpNode"; + + private final static DateFormat df = new SimpleDateFormat( + "yyyy-MM-dd_HH-mm"); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + Iterator lst = ((IStructuredSelection) selection).iterator(); + if (lst.hasNext()) { + Object element = lst.next(); + if (element instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; + Node node = sjn.getNode(); + + // TODO add a dialog to configure the export and ask for + // confirmation + // Boolean ok = MessageDialog.openConfirm( + // HandlerUtil.getActiveShell(event), "Confirm deletion", + // "Do you want to delete " + buf + "?"); + + File tmpFile; + FileOutputStream fos; + try { + tmpFile = File.createTempFile("JcrExport", ".xml"); + tmpFile.deleteOnExit(); + fos = new FileOutputStream(tmpFile); + String dateVal = df.format(new GregorianCalendar() + .getTime()); + node.getSession().exportSystemView(node.getPath(), fos, + true, false); + openGeneratedFile(tmpFile.getAbsolutePath(), "Dump-" + + JcrUtils.replaceInvalidChars(node.getName()) + + "-" + dateVal + ".xml"); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unable to perform SystemExport on " + node, e); + } catch (IOException e) { + throw new EclipseUiException("Unable to SystemExport " + + node, e); + } + } + } + return null; + } + + private synchronized void openGeneratedFile(String path, String fileName) { + Map params = new HashMap(); + params.put(OpenFile.PARAM_FILE_NAME, fileName); + params.put(OpenFile.PARAM_FILE_URI, "file://" + path); + CommandUtils.callCommand(OpenFile.ID, params); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java new file mode 100644 index 000000000..3acd6e827 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Property; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodeEditorInput; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Generic command to open a path in an editor. */ +public class EditNode extends AbstractHandler { + public final static String EDITOR_PARAM = "editor"; + + private String defaultEditorId; + + private Map nodeTypeToEditor = new HashMap(); + + public Object execute(ExecutionEvent event) throws ExecutionException { + String path = event.getParameter(Property.JCR_PATH); + + String type = event.getParameter(NodeType.NT_NODE_TYPE); + if (type == null) + type = NodeType.NT_UNSTRUCTURED; + + String editorId = event.getParameter(NodeType.NT_NODE_TYPE); + if (editorId == null) + editorId = nodeTypeToEditor.containsKey(type) ? nodeTypeToEditor + .get(type) : defaultEditorId; + + NodeEditorInput nei = new NodeEditorInput(path); + + try { + HandlerUtil.getActiveWorkbenchWindow(event).getActivePage() + .openEditor(nei, editorId); + } catch (PartInitException e) { + ErrorFeedback.show("Cannot open " + editorId + " with " + path + + " of type " + type, e); + } + // TODO Auto-generated method stub + return null; + } + + public void setDefaultEditorId(String defaultEditorId) { + this.defaultEditorId = defaultEditorId; + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java new file mode 100644 index 000000000..0240e35d1 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.jcr.Node; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +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; + +/** Compute an approximative size for the selected node(s) */ +public class GetNodeSize extends AbstractHandler { + // private final static Log log = LogFactory.getLog(GetNodeSize.class); + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".getNodeSize"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + + long size = 0; + + Iterator it = ((IStructuredSelection) selection).iterator(); + + // TODO enhance this: as the size method is recursive, we keep track + // of nodes for which we already have computed size so that we don't + // count them twice. In a first approximation, we assume that the + // structure selection keep the nodes ordered. + List importedPathes = new ArrayList(); + try { + nodesIt: while (it.hasNext()) { + Object obj = it.next(); + String curPath; + Node node; + if (obj instanceof SingleJcrNodeElem) { + node = ((SingleJcrNodeElem) obj).getNode(); + curPath = node.getSession().getWorkspace().getName(); + curPath += "/" + node.getPath(); + } else if (obj instanceof WorkspaceElem) { + node = ((WorkspaceElem) obj).getRootNode(); + curPath = node.getSession().getWorkspace().getName(); + } else + // non valid object type + continue nodesIt; + + Iterator itPath = importedPathes.iterator(); + while (itPath.hasNext()) { + String refPath = itPath.next(); + if (curPath.startsWith(refPath)) + // Already done : skip node + continue nodesIt; + } + size += JcrUtils.getNodeApproxSize(node); + importedPathes.add(curPath); + } + } catch (Exception e) { + ErrorFeedback.show("Cannot Get size of selected node ", e); + } + + 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; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ImportFileSystem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ImportFileSystem.java new file mode 100644 index 000000000..0493ffeb4 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ImportFileSystem.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import javax.jcr.Node; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.internal.jcr.parts.ImportFileSystemWizard; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +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.jface.wizard.WizardDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Import a local file system directory tree. */ +public class ImportFileSystem extends AbstractHandler { + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + try { + Node folder = null; + if (obj instanceof SingleJcrNodeElem) { + folder = ((SingleJcrNodeElem) obj).getNode(); + } else if (obj instanceof WorkspaceElem) { + folder = ((WorkspaceElem) obj).getRootNode(); + } else { + ErrorFeedback.show(WorkbenchUiPlugin + .getMessage("warningInvalidNodeToImport")); + } + if (folder != null) { + ImportFileSystemWizard wizard = new ImportFileSystemWizard( + folder); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + dialog.open(); + view.nodeAdded((TreeParent) obj); + } + } catch (Exception e) { + ErrorFeedback.show("Cannot import files to " + obj, e); + } + } + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/NodeConfigurableDump.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/NodeConfigurableDump.java new file mode 100644 index 000000000..95f4e346c --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/NodeConfigurableDump.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +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.jface.window.Window; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +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.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * First draft of a wizard that enable configurable recursive dump of the + * current selected Node (Only one at a time). Enable among other to export + * children Nodes and to choose to export binaries or not. It is useful to + * retrieve business data from live systems to prepare migration or test locally + */ +public class NodeConfigurableDump extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".nodeConfigurableDump"; + + private final static DateFormat df = new SimpleDateFormat( + "yyyy-MM-dd_HH-mm"); + + public final static int EXPORT_NODE = 0; + public final static int EXPORT_CHILDREN = 1; + public final static int EXPORT_GRAND_CHILDREN = 2; + + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + Iterator lst = ((IStructuredSelection) selection).iterator(); + if (lst.hasNext()) { + Object element = lst.next(); + if (element instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; + Node node = sjn.getNode(); + + ConfigureDumpWizard wizard = new ConfigureDumpWizard( + HandlerUtil.getActiveShell(event), + "Import Resource CSV"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + int result = dialog.open(); + + if (result == Window.OK) { + + String dateVal = df.format(new GregorianCalendar() + .getTime()); + try { + + Path tmpDirPath = Files.createTempDirectory(dateVal + + "-NodeDump-"); + List toExport = retrieveToExportNodes(node, + wizard.currExportType); + + for (Node currNode : toExport) { + FileOutputStream fos; + String fileName = wizard.prefix + + JcrUtils.replaceInvalidChars(currNode + .getName()) + "_" + dateVal + + ".xml"; + File currFile = new File(tmpDirPath.toString() + + "/" + fileName); + currFile.createNewFile(); + fos = new FileOutputStream(currFile); + node.getSession().exportSystemView( + currNode.getPath(), fos, + !wizard.includeBinaries, false); + fos.flush(); + fos.close(); + } + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unable to perform SystemExport on " + node, e); + } catch (IOException e) { + throw new EclipseUiException("Unable to SystemExport " + + node, e); + } + } + } + } + return null; + } + + private List retrieveToExportNodes(Node node, int currExportType) + throws RepositoryException { + List nodes = new ArrayList(); + switch (currExportType) { + case EXPORT_NODE: + nodes.add(node); + return nodes; + case EXPORT_CHILDREN: + return JcrUtils.nodeIteratorToList(node.getNodes()); + case EXPORT_GRAND_CHILDREN: + NodeIterator nit = node.getNodes(); + while (nit.hasNext()) + nodes.addAll(JcrUtils.nodeIteratorToList(nit.nextNode() + .getNodes())); + return nodes; + + default: + return nodes; + } + } + + // private synchronized void openGeneratedFile(String path, String fileName) + // { + // Map params = new HashMap(); + // params.put(OpenFile.PARAM_FILE_NAME, fileName); + // params.put(OpenFile.PARAM_FILE_URI, "file://" + path); + // CommandUtils.callCommand("org.argeo.security.ui.specific.openFile", + // params); + // } + + private class ConfigureDumpWizard extends Wizard { + + // parameters + protected String prefix; + protected int currExportType = EXPORT_NODE; + protected boolean includeBinaries = false; + + // UI Objects + private BasicPage page; + private Text prefixTxt; + private Button includeBinaryBtn; + private Button b1, b2, b3; + + public ConfigureDumpWizard(Shell parentShell, String title) { + setWindowTitle(title); + } + + @Override + public void addPages() { + try { + page = new BasicPage("Main page"); + addPage(page); + } catch (Exception e) { + throw new EclipseUiException("Cannot add page to wizard", e); + } + } + + @Override + public boolean performFinish() { + prefix = prefixTxt.getText(); + if (b1.getSelection()) + currExportType = EXPORT_NODE; + else if (b2.getSelection()) + currExportType = EXPORT_CHILDREN; + else if (b3.getSelection()) + currExportType = EXPORT_GRAND_CHILDREN; + includeBinaries = includeBinaryBtn.getSelection(); + return true; + } + + @Override + public boolean performCancel() { + return true; + } + + @Override + public boolean canFinish() { + String errorMsg = "No prefix defined."; + if ("".equals(prefixTxt.getText().trim())) { + page.setErrorMessage(errorMsg); + return false; + } else { + page.setErrorMessage(null); + return true; + } + } + + protected class BasicPage extends WizardPage { + private static final long serialVersionUID = 1L; + + public BasicPage(String pageName) { + super(pageName); + setTitle("Configure dump before launching"); + setMessage("Define the parameters of the dump to launch"); + } + + public void createControl(Composite parent) { + parent.setLayout(noSpaceGridLayout()); + + // Main Layout + Composite mainCmp = new Composite(parent, SWT.NONE); + mainCmp.setLayout(new GridLayout(2, false)); + mainCmp.setLayoutData(fillAll()); + + // The path + createBoldLabel(mainCmp, "Prefix"); + prefixTxt = new Text(mainCmp, SWT.SINGLE | SWT.BORDER); + prefixTxt.setLayoutData(fillAll()); + prefixTxt.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = 1L; + + @Override + public void modifyText(ModifyEvent event) { + if (prefixTxt.getText() != null) + getWizard().getContainer().updateButtons(); + } + }); + + new Label(mainCmp, SWT.SEPARATOR | SWT.HORIZONTAL) + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false, 2, 1)); + + // Which node to export + Label typeLbl = new Label(mainCmp, SWT.RIGHT); + typeLbl.setText(" Type"); + typeLbl.setFont(EclipseUiUtils.getBoldFont(mainCmp)); + typeLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, + false, 1, 3)); + + b1 = new Button(mainCmp, SWT.RADIO); + b1.setText("Export this node"); + b1.setSelection(true); + b2 = new Button(mainCmp, SWT.RADIO); + b2.setText("Export children nodes"); + b3 = new Button(mainCmp, SWT.RADIO); + b3.setText("Export grand-children nodes"); + + new Label(mainCmp, SWT.SEPARATOR | SWT.HORIZONTAL) + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false, 2, 1)); + + createBoldLabel(mainCmp, "Files and images"); + includeBinaryBtn = new Button(mainCmp, SWT.CHECK); + includeBinaryBtn.setText("Include binaries"); + + prefixTxt.setFocus(); + setControl(mainCmp); + } + } + } + + private Label createBoldLabel(Composite parent, String value) { + Label label = new Label(parent, SWT.RIGHT); + label.setText(" " + value); + label.setFont(EclipseUiUtils.getBoldFont(parent)); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + return label; + } + + // TODO rather use EclipseUiUtils methods + private GridLayout noSpaceGridLayout() { + return noSpaceGridLayout(new GridLayout()); + } + + private GridLayout noSpaceGridLayout(GridLayout layout) { + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 0; + return layout; + } + + private GridData fillAll() { + return new GridData(SWT.FILL, SWT.FILL, true, true); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java new file mode 100644 index 000000000..51b2a1d92 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.util.Iterator; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.JcrBrowserUtils; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.TreeParent; +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; + +/** + * Force the selected objects of the active view to be refreshed doing the + * following: + *
    + *
  1. The model objects are recomputed
  2. + *
  3. the view is refreshed
  4. + *
+ */ +public class Refresh extends AbstractHandler { + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".refresh"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + JcrBrowserView view = (JcrBrowserView) WorkbenchUiPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow().getActivePage() + .getActivePart();// + + ISelection selection = WorkbenchUiPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getSelection(); + + if (selection != null && selection instanceof IStructuredSelection + && !selection.isEmpty()) { + Iterator it = ((IStructuredSelection) selection).iterator(); + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof TreeParent) { + TreeParent tp = (TreeParent) obj; + JcrBrowserUtils.forceRefreshIfNeeded(tp); + view.refresh(obj); + } + } + } else if (view instanceof JcrBrowserView) + ((JcrBrowserView) view).refresh(null); // force full refresh + + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java new file mode 100644 index 000000000..3e78a4b4a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.security.Principal; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.AccessControlList; +import javax.jcr.security.AccessControlManager; +import javax.jcr.security.Privilege; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.internal.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.jcr.JcrImages; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Open a dialog to remove privileges from the selected node */ +public class RemovePrivileges extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".removePrivileges"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + TreeParent uiNode = null; + Node jcrNode = null; + + if (obj instanceof SingleJcrNodeElem) { + uiNode = (TreeParent) obj; + jcrNode = ((SingleJcrNodeElem) uiNode).getNode(); + } else if (obj instanceof WorkspaceElem) { + uiNode = (TreeParent) obj; + jcrNode = ((WorkspaceElem) uiNode).getRootNode(); + } else + return null; + + try { + String targetPath = jcrNode.getPath(); + Dialog dialog = new RemovePrivDialog( + HandlerUtil.getActiveShell(event), + jcrNode.getSession(), targetPath); + dialog.open(); + return null; + } catch (RepositoryException re) { + throw new EclipseUiException("Unable to retrieve " + + "path or JCR session to add privilege on " + jcrNode, + re); + } + } else { + ErrorFeedback.show("Cannot add privileges"); + } + return null; + } + + private class RemovePrivDialog extends TitleAreaDialog { + private static final long serialVersionUID = 280139710002698692L; + + private Composite body; + + private final String path; + private final Session session; + + public RemovePrivDialog(Shell parentShell, Session session, String path) { + super(parentShell); + this.session = session; + this.path = path; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Remove privileges"); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, + true)); + body = new Composite(dialogarea, SWT.NONE); + body.setLayoutData(EclipseUiUtils.fillAll()); + refreshContent(); + parent.pack(); + return body; + } + + private void refreshContent() { + EclipseUiUtils.clear(body); + try { + AccessControlManager acm = session.getAccessControlManager(); + AccessControlList acl = JcrUtils + .getAccessControlList(acm, path); + if (acl == null || acl.getAccessControlEntries().length <= 0) + setMessage("No privilege are defined on this node", + IMessageProvider.INFORMATION); + else { + body.setLayout(new GridLayout(3, false)); + for (AccessControlEntry ace : acl.getAccessControlEntries()) { + addOnePrivRow(body, ace); + } + setMessage("Remove some of the defined privileges", + IMessageProvider.INFORMATION); + } + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to list privileges on " + + path, e); + } + body.layout(true, true); + } + + private void addOnePrivRow(Composite parent, AccessControlEntry ace) { + Principal currentPrincipal = ace.getPrincipal(); + final String currPrincipalName = currentPrincipal.getName(); + new Label(parent, SWT.WRAP).setText(currPrincipalName); + new Label(parent, SWT.WRAP).setText(privAsString(ace + .getPrivileges())); + final Button rmBtn = new Button(parent, SWT.FLAT); + rmBtn.setImage(JcrImages.REMOVE); + + rmBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 7566938841363890730L; + + @Override + public void widgetSelected(SelectionEvent e) { + + if (MessageDialog.openConfirm(rmBtn.getShell(), + "Confirm deletion", + "Are you sure you want to remove this privilege?")) { + try { + session.save(); + JcrUtils.clearAccessControList(session, path, + currPrincipalName); + session.save(); + refreshContent(); + } catch (RepositoryException re) { + throw new EclipseUiException("Unable to " + + "remove privilege for " + + currPrincipalName + " on " + path, re); + } + } + + super.widgetSelected(e); + } + }); + + } + + private String privAsString(Privilege[] currentPrivileges) { + + StringBuilder builder = new StringBuilder(); + builder.append("[ "); + for (Privilege priv : currentPrivileges) { + builder.append(priv.getName()).append(", "); + } + if (builder.length() > 3) + return builder.substring(0, builder.length() - 2) + " ]"; + else + return "[]"; + + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java new file mode 100644 index 000000000..cd49bf0c1 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import org.argeo.cms.ui.workbench.internal.jcr.model.RemoteRepositoryElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +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; + +/** Remove a registered remote repository */ +public class RemoveRemoteRepository extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + + if (obj instanceof RemoteRepositoryElem) { + ((RemoteRepositoryElem) obj).remove(); + view.refresh(null); + } + } + return null; + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java new file mode 100644 index 000000000..fefc551cf --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import java.util.Iterator; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.dialogs.SingleValue; +import org.argeo.jcr.JcrUtils; +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.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Canonically call JCR {@link Session#move(String, String)} on the first + * element returned by {@link HandlerUtil#getActiveWorkbenchWindow()} + * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}. + * The user must then fill a new name in and confirm + */ +public class RenameNode extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".renameNode"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage(); + + ISelection selection = iwp.getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + Iterator lst = ((IStructuredSelection) selection).iterator(); + if (lst.hasNext()) { + Object element = lst.next(); + if (element instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; + Node node = sjn.getNode(); + Session session = null; + String newName = null; + String oldPath = null; + try { + newName = SingleValue.ask("New node name", + "Please provide a new name for [" + node.getName() + + "]"); + // TODO sanity check and user feedback + newName = JcrUtils.replaceInvalidChars(newName); + oldPath = node.getPath(); + session = node.getSession(); + session.move(oldPath, JcrUtils.parentPath(oldPath) + "/" + + newName); + session.save(); + + // Manually refresh the browser view. Must be enhanced + if (iwp.getActivePart() instanceof JcrBrowserView) + ((JcrBrowserView) iwp.getActivePart()).refresh(sjn); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to rename " + node + + " to " + newName, e); + } + } + } + return null; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java new file mode 100644 index 000000000..4b3d6f308 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.State; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Change isSorted state of the DataExplorer Browser */ +public class SortChildNodes extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".sortChildNodes"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(JcrBrowserView.ID); + + ICommandService service = (ICommandService) PlatformUI.getWorkbench() + .getService(ICommandService.class); + Command command = service.getCommand(ID); + State state = command.getState(ID + ".toggleState"); + + boolean wasSorted = (Boolean) state.getValue(); + view.setSortChildNodes(!wasSorted); + state.setValue(!wasSorted); + return null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/MaintainedRepositoryElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/MaintainedRepositoryElem.java new file mode 100644 index 000000000..bebdc66dc --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/MaintainedRepositoryElem.java @@ -0,0 +1,21 @@ +package org.argeo.cms.ui.workbench.internal.jcr.model; + +import javax.jcr.Repository; + +import org.argeo.eclipse.ui.TreeParent; + +/** Wrap a MaintainedRepository */ +public class MaintainedRepositoryElem extends RepositoryElem { + + public MaintainedRepositoryElem(String alias, Repository repository, TreeParent parent) { + super(alias, repository, parent); + // if (!(repository instanceof MaintainedRepository)) { + // throw new ArgeoException("Repository " + alias + // + " is not amiantained repository"); + // } + } + + // protected MaintainedRepository getMaintainedRepository() { + // return (MaintainedRepository) getRepository(); + // } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RemoteRepositoryElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RemoteRepositoryElem.java new file mode 100644 index 000000000..f34f4de24 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RemoteRepositoryElem.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.model; + +import java.util.Arrays; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.node.ArgeoNames; +import org.argeo.node.NodeUtils; +import org.argeo.node.security.Keyring; + +/** Root of a remote repository */ +public class RemoteRepositoryElem extends RepositoryElem { + private final Keyring keyring; + /** + * A session of the logged in user on the default workspace of the node + * repository. + */ + private final Session userSession; + private final String remoteNodePath; + + private final RepositoryFactory repositoryFactory; + private final String uri; + + public RemoteRepositoryElem(String alias, + RepositoryFactory repositoryFactory, String uri, TreeParent parent, + Session userSession, Keyring keyring, String remoteNodePath) { + super(alias, null, parent); + this.repositoryFactory = repositoryFactory; + this.uri = uri; + this.keyring = keyring; + this.userSession = userSession; + this.remoteNodePath = remoteNodePath; + } + + @Override + protected Session repositoryLogin(String workspaceName) + throws RepositoryException { + Node remoteRepository = userSession.getNode(remoteNodePath); + String userID = remoteRepository.getProperty(ArgeoNames.ARGEO_USER_ID) + .getString(); + String pwdPath = remoteRepository.getPath() + '/' + + ArgeoNames.ARGEO_PASSWORD; + char[] password = keyring.getAsChars(pwdPath); + + try { + SimpleCredentials credentials = new SimpleCredentials(userID, + password); + return getRepository().login(credentials, workspaceName); + } finally { + Arrays.fill(password, 0, password.length, ' '); + } + } + + @Override + public Repository getRepository() { + if (repository == null) + repository = NodeUtils.getRepositoryByUri(repositoryFactory, + uri); + return super.getRepository(); + } + + public void remove() { + try { + Node remoteNode = userSession.getNode(remoteNodePath); + remoteNode.remove(); + remoteNode.getSession().save(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot remove " + remoteNodePath, e); + } + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RepositoriesElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RepositoriesElem.java new file mode 100644 index 000000000..7a162c18f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RepositoriesElem.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.model; + +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.RepositoryRegister; +import org.argeo.node.ArgeoNames; +import org.argeo.node.NodeUtils; +import org.argeo.node.security.Keyring; + +/** + * UI Tree component that 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 RepositoriesElem extends TreeParent implements ArgeoNames { + private final RepositoryRegister repositoryRegister; + private final RepositoryFactory repositoryFactory; + + /** + * A session of the logged in user on the default workspace of the node + * repository. + */ + private final Session userSession; + private final Keyring keyring; + + public RepositoriesElem(String name, RepositoryRegister repositoryRegister, RepositoryFactory repositoryFactory, + TreeParent parent, Session userSession, Keyring keyring) { + super(name); + this.repositoryRegister = repositoryRegister; + this.repositoryFactory = repositoryFactory; + this.userSession = userSession; + this.keyring = keyring; + } + + /** + * Override normal behavior 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()) { + Repository repository = refRepos.get(name); + // if (repository instanceof MaintainedRepository) + // super.addChild(new MaintainedRepositoryElem(name, + // repository, this)); + // else + super.addChild(new RepositoryElem(name, repository, this)); + } + + // remote + if (keyring != null) { + try { + addRemoteRepositories(keyring); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot browse remote repositories", e); + } + } + return super.getChildren(); + } + } + + protected void addRemoteRepositories(Keyring jcrKeyring) throws RepositoryException { + Node userHome = NodeUtils.getUserHome(userSession); + if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) { + NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes(); + while (it.hasNext()) { + Node remoteNode = it.nextNode(); + String uri = remoteNode.getProperty(ARGEO_URI).getString(); + try { + RemoteRepositoryElem remoteRepositoryNode = new RemoteRepositoryElem(remoteNode.getName(), + repositoryFactory, uri, this, userSession, jcrKeyring, remoteNode.getPath()); + super.addChild(remoteRepositoryNode); + } catch (Exception e) { + ErrorFeedback.show("Cannot add remote repository " + remoteNode, e); + } + } + } + } + + 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 this object. */ + public RepositoryRegister getRepositoryRegister() { + return repositoryRegister; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RepositoryElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RepositoryElem.java new file mode 100644 index 000000000..6657adfd0 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/RepositoryElem.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.model; + +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; + +/** + * UI Tree component that 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 RepositoryElem extends TreeParent { + private String alias; + protected Repository repository; + private Session defaultSession = null; + + /** Create a new repository with distinct name & alias */ + public RepositoryElem(String alias, Repository repository, TreeParent parent) { + super(alias); + this.repository = repository; + setParent(parent); + this.alias = alias; + } + + public void login() { + try { + defaultSession = repositoryLogin("main"); + String[] wkpNames = defaultSession.getWorkspace() + .getAccessibleWorkspaceNames(); + for (String wkpName : wkpNames) { + if (wkpName.equals(defaultSession.getWorkspace().getName())) + addChild(new WorkspaceElem(this, wkpName, defaultSession)); + else + addChild(new WorkspaceElem(this, wkpName)); + } + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot connect to repository " + alias, e); + } + } + + /** + * Actual call to the + * {@link Repository#login(javax.jcr.Credentials, String)} method. To be + * overridden. + */ + protected Session repositoryLogin(String workspaceName) + throws RepositoryException { + return repository.login(workspaceName); + } + + public String[] getAccessibleWorkspaceNames() { + try { + return defaultSession.getWorkspace().getAccessibleWorkspaceNames(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot retrieve workspace names", e); + } + } + + public void createWorkspace(String workspaceName) { + if (!isConnected()) + login(); + try { + defaultSession.getWorkspace().createWorkspace(workspaceName); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot create workspace", e); + } + } + + /** returns the {@link Repository} referenced by the current UI Node */ + public Repository getRepository() { + return repository; + } + + public String getAlias() { + return alias; + } + + public Boolean isConnected() { + if (defaultSession != null && defaultSession.isLive()) + return true; + else + return false; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/SingleJcrNodeElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/SingleJcrNodeElem.java new file mode 100644 index 000000000..c27a13c2f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/SingleJcrNodeElem.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.model; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Workspace; + +import org.argeo.eclipse.ui.EclipseUiException; +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 WorkspaceElem}, a + * {@link SingleJcrNodeElem} or null if the node is "mounted" as the root of the UI + * tree. + */ + +public class SingleJcrNodeElem extends TreeParent { + + 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 SingleJcrNodeElem(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 SingleJcrNodeElem(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; + } + + protected String getRepositoryAlias() { + return alias; + } + + /** + * Override normal behavior 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 SingleJcrNodeElem(this, curNode, curNode.getName())); + } + return super.getChildren(); + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexcpected error while initializing children SingleJcrNode", + re); + } + } + } + + @Override + public boolean hasChildren() { + try { + if (node.getSession().isLive()) + return node.hasNodes(); + else + return false; + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while checking children node existence", + re); + } + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/WorkspaceElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/WorkspaceElem.java new file mode 100644 index 000000000..0bbd774d5 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/model/WorkspaceElem.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.model; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +// import javax.jcr.Workspace; +import javax.jcr.Workspace; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.jcr.JcrUtils; + +/** + * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also + * keeps a reference to its parent {@link RepositoryElem}, to be able to + * retrieve alias of the current used repository + */ +public class WorkspaceElem extends TreeParent { + private Session session = null; + + public WorkspaceElem(RepositoryElem parent, String name) { + this(parent, name, null); + } + + public WorkspaceElem(RepositoryElem parent, String name, Session session) { + super(name); + this.session = session; + setParent(parent); + } + + public synchronized Session getSession() { + return session; + } + + public synchronized Node getRootNode() { + try { + if (session != null) + return session.getRootNode(); + else + return null; + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot get root node of workspace " + + getName(), e); + } + } + + public synchronized void login() { + try { + session = ((RepositoryElem) getParent()).repositoryLogin(getName()); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot connect to repository " + + getName(), e); + } + } + + public Boolean isConnected() { + if (session != null && session.isLive()) + return true; + else + return false; + } + + @Override + public synchronized void dispose() { + logout(); + super.dispose(); + } + + /** Logouts the session, does not nothing if there is no live session. */ + public synchronized void logout() { + clearChildren(); + JcrUtils.logoutQuietly(session); + session = null; + } + + @Override + public synchronized boolean hasChildren() { + try { + if (isConnected()) + return session.getRootNode().hasNodes(); + else + return false; + } catch (RepositoryException re) { + throw new EclipseUiException( + "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 SingleJcrNodeElem(this, node, node.getName())); + } + return super.getChildren(); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Cannot initialize WorkspaceNode UI object." + + getName(), e); + } + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java new file mode 100644 index 000000000..27c7cdb15 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +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.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.GenericTableComparator; +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.IDoubleClickListener; +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.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.swt.widgets.TableColumn; +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 { + private final static Log log = LogFactory + .getLog(AbstractJcrQueryEditor.class); + + protected String initialQuery; + protected String initialQueryType; + + /* DEPENDENCY INJECTION */ + private Session session; + + // Widgets + private TableViewer viewer; + private List tableViewerColumns = new ArrayList(); + private GenericTableComparator comparator; + + /** Override to layout a form enabling the end user to build his query */ + 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(4); + sashForm.setLayout(new FillLayout()); + + Composite top = new Composite(sashForm, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + top.setLayout(gl); + + createQueryForm(top); + + Composite bottom = new Composite(sashForm, SWT.NONE); + bottom.setLayout(new GridLayout(1, false)); + sashForm.setWeights(getWeights()); + + viewer = new TableViewer(bottom); + viewer.getTable().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + viewer.getTable().setHeaderVisible(true); + viewer.setContentProvider(getQueryResultContentProvider()); + viewer.setInput(getEditorSite()); + + if (getComparator() != null) { + comparator = getComparator(); + viewer.setComparator(comparator); + } + if (getTableDoubleClickListener() != null) + viewer.addDoubleClickListener(getTableDoubleClickListener()); + + } + + protected void executeQuery(String statement) { + try { + if (log.isDebugEnabled()) + log.debug("Query : " + statement); + + QueryResult qr = session.getWorkspace().getQueryManager() + .createQuery(statement, initialQueryType).execute(); + + // remove previous columns + for (TableViewerColumn tvc : tableViewerColumns) + tvc.getColumn().dispose(); + + int i = 0; + for (final String columnName : qr.getColumnNames()) { + TableViewerColumn tvc = new TableViewerColumn(viewer, SWT.NONE); + configureColumn(columnName, tvc, i); + tvc.setLabelProvider(getLabelProvider(columnName)); + tableViewerColumns.add(tvc); + i++; + } + + // Must create a local list: QueryResults can only be read once. + try { + List rows = new ArrayList(); + RowIterator rit = qr.getRows(); + while (rit.hasNext()) { + rows.add(rit.nextRow()); + } + viewer.setInput(rows); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot read query result", e); + } + + } catch (RepositoryException e) { + ErrorDialog.openError(null, "Error", "Cannot execute JCR query: " + + statement, new Status(IStatus.ERROR, + "org.argeo.eclipse.ui.jcr", e.getMessage())); + } + } + + /** + * To be overidden to adapt size of form and result frames. + * + * @return + */ + protected int[] getWeights() { + return new int[] { 30, 70 }; + } + + /** + * To be overidden to implement a doubleclick Listener on one of the rows of + * the table. + * + * @return + */ + protected IDoubleClickListener getTableDoubleClickListener() { + return null; + } + + /** + * To be overiden in order to implement a specific + * QueryResultContentProvider + */ + protected IStructuredContentProvider getQueryResultContentProvider() { + return new QueryResultContentProvider(); + } + + /** + * Enable specific implementation for columns + */ + protected List getTableViewerColumns() { + return tableViewerColumns; + } + + /** + * Enable specific implementation for columns + */ + protected TableViewer getTableViewer() { + return viewer; + } + + /** + * To be overridden in order to configure column label providers . + */ + protected ColumnLabelProvider getLabelProvider(final String columnName) { + return new ColumnLabelProvider() { + private static final long serialVersionUID = -3539689333250152606L; + + public String getText(Object element) { + Row row = (Row) element; + try { + return row.getValue(columnName).getString(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot display row " + row, e); + } + } + + public Image getImage(Object element) { + return null; + } + }; + } + + /** + * To be overridden in order to configure the columns. + * + * @deprecated use {@link + * org.argeo.eclipse.ui.jcr.editors.AbstractJcrQueryEditor. + * configureColumn(String jcrColumnName, TableViewerColumn + * column, int columnIndex)} instead + */ + protected void configureColumn(String jcrColumnName, + TableViewerColumn column) { + column.getColumn().setWidth(50); + column.getColumn().setText(jcrColumnName); + } + + /** To be overridden in order to configure the columns. */ + protected void configureColumn(String jcrColumnName, + TableViewerColumn column, int columnIndex) { + column.getColumn().setWidth(50); + column.getColumn().setText(jcrColumnName); + } + + private class QueryResultContentProvider implements + IStructuredContentProvider { + private static final long serialVersionUID = -5421095459600554741L; + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getElements(Object inputElement) { + + if (inputElement instanceof List) + return ((List) inputElement).toArray(); + + // Never reached might be deleted in future release + 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 EclipseUiException("Cannot read query result", e); + } + } + + } + + /** + * Might be used by children classes to sort columns. + * + * @param column + * @param index + * @return + */ + protected SelectionAdapter getSelectionAdapter(final TableColumn column, + final int index) { + + // A comparator must be define + if (comparator == null) + return null; + + SelectionAdapter selectionAdapter = new SelectionAdapter() { + private static final long serialVersionUID = 239829307927778349L; + + @Override + public void widgetSelected(SelectionEvent e) { + + try { + + comparator.setColumn(index); + int dir = viewer.getTable().getSortDirection(); + if (viewer.getTable().getSortColumn() == column) { + dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; + } else { + + dir = SWT.DOWN; + } + viewer.getTable().setSortDirection(dir); + viewer.getTable().setSortColumn(column); + viewer.refresh(); + } catch (Exception exc) { + exc.printStackTrace(); + } + } + }; + return selectionAdapter; + } + + /** + * To be overridden to enable sorting. + */ + protected GenericTableComparator getComparator() { + 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; + } + + /** Returns the injected current session */ + protected Session getSession() { + return session; + } + + /* DEPENDENCY INJECTION */ + public void setSession(Session session) { + this.session = session; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java new file mode 100644 index 000000000..0e6c34c55 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.security.Privilege; + +import org.argeo.cms.ui.workbench.internal.useradmin.UsersUtils; +import org.argeo.cms.ui.workbench.useradmin.PickUpUserDialog; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Add JCR privileges to the chosen user group on a given node */ +public class AddPrivilegeWizard extends Wizard { + + // Context + private UserAdmin userAdmin; + private Session currentSession; + private String targetPath; + // Chosen parameters + private User chosenUser; + private String jcrPrivilege; + + // UI Object + private DefinePrivilegePage page; + + // TODO enable external definition of possible values and corresponding + // description + protected static final Map AUTH_TYPE_LABELS; + static { + Map tmpMap = new HashMap(); + tmpMap.put(Privilege.JCR_READ, "jcr:read"); + tmpMap.put(Privilege.JCR_WRITE, "jcr:write"); + tmpMap.put(Privilege.JCR_ALL, "jcr:all"); + AUTH_TYPE_LABELS = Collections.unmodifiableMap(tmpMap); + } + + protected static final Map AUTH_TYPE_DESC; + static { + Map tmpMap = new HashMap(); + tmpMap.put(Privilege.JCR_READ, + "The privilege to retrieve a node and get its properties and their values."); + tmpMap.put(Privilege.JCR_WRITE, "An aggregate privilege that " + + "contains: jcr:modifyProperties, jcr:addChildNodes, " + + "jcr:removeNode, jcr:removeChildNodes"); + tmpMap.put(Privilege.JCR_ALL, "An aggregate privilege that " + + "contains all JCR predefined privileges, " + + "plus all implementation-defined privileges. "); + AUTH_TYPE_DESC = Collections.unmodifiableMap(tmpMap); + } + + public AddPrivilegeWizard(Session currentSession, String path, + UserAdmin userAdmin) { + super(); + this.userAdmin = userAdmin; + this.currentSession = currentSession; + this.targetPath = path; + } + + @Override + public void addPages() { + try { + setWindowTitle("Add privilege on " + targetPath); + page = new DefinePrivilegePage(userAdmin, targetPath); + addPage(page); + } catch (Exception e) { + throw new EclipseUiException("Cannot add page to wizard ", e); + } + } + + @Override + public boolean performFinish() { + if (!canFinish()) + return false; + try { + JcrUtils.addPrivilege(currentSession, targetPath, + chosenUser.getName(), jcrPrivilege); + } catch (RepositoryException re) { + throw new EclipseUiException("Cannot set " + jcrPrivilege + " for " + + chosenUser.getName() + " on " + targetPath, re); + } + return true; + } + + private class DefinePrivilegePage extends WizardPage implements + ModifyListener { + private static final long serialVersionUID = 8084431378762283920L; + + // Context + final private UserAdmin userAdmin; + + public DefinePrivilegePage(UserAdmin userAdmin, String path) { + super("Main"); + this.userAdmin = userAdmin; + setTitle("Define the privilege to apply to " + path); + setMessage("Please choose a user or a group and relevant JCR Privilege."); + } + + public void createControl(Composite parent) { + final Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(3, false)); + + // specify subject + createBoldLabel(composite, "User or group name"); + final Label groupNameLbl = new Label(composite, SWT.LEAD); + groupNameLbl.setLayoutData(EclipseUiUtils.fillWidth()); + + Link pickUpLk = new Link(composite, SWT.LEFT); + pickUpLk.setText(" Change "); + + createBoldLabel(composite, "User or group DN"); + final Text groupNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER); + groupNameTxt.setLayoutData(EclipseUiUtils.fillWidth(2)); + + pickUpLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + PickUpUserDialog dialog = new PickUpUserDialog(getShell(), + "Choose a group or a user", userAdmin); + if (dialog.open() == Window.OK) { + chosenUser = dialog.getSelected(); + groupNameLbl.setText(UsersUtils + .getCommonName(chosenUser)); + groupNameTxt.setText(chosenUser.getName()); + } + } + }); + + groupNameTxt.addFocusListener(new FocusListener() { + private static final long serialVersionUID = 1965498600105667738L; + + @Override + public void focusLost(FocusEvent event) { + String dn = groupNameTxt.getText(); + if (EclipseUiUtils.isEmpty(dn)) + return; + + User newChosen = null; + try { + newChosen = (User) userAdmin.getRole(dn); + } catch (Exception e) { + boolean tryAgain = MessageDialog.openQuestion( + getShell(), "Unvalid DN", + "DN " + dn + " is not valid.\nError message: " + + e.getMessage() + + "\n\t\tDo you want to try again?"); + if (tryAgain) + groupNameTxt.setFocus(); + else + resetOnFail(); + } + + if (userAdmin.getRole(dn) == null) { + boolean tryAgain = MessageDialog.openQuestion( + getShell(), "Unexisting role", "User/group " + + dn + " does not exist. " + + "Do you want to try again?"); + if (tryAgain) + groupNameTxt.setFocus(); + else + resetOnFail(); + } else { + chosenUser = newChosen; + groupNameLbl.setText(UsersUtils + .getCommonName(chosenUser)); + } + } + + private void resetOnFail() { + String oldDn = chosenUser == null ? "" : chosenUser + .getName(); + groupNameTxt.setText(oldDn); + } + + @Override + public void focusGained(FocusEvent event) { + } + }); + + // JCR Privileges + createBoldLabel(composite, "Privilege type"); + Combo authorizationCmb = new Combo(composite, SWT.BORDER + | SWT.READ_ONLY | SWT.V_SCROLL); + authorizationCmb.setItems(AUTH_TYPE_LABELS.values().toArray( + new String[0])); + authorizationCmb.setLayoutData(EclipseUiUtils.fillWidth(2)); + createBoldLabel(composite, ""); // empty cell + final Label descLbl = new Label(composite, SWT.WRAP); + descLbl.setLayoutData(EclipseUiUtils.fillWidth(2)); + + authorizationCmb.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + String chosenPrivStr = ((Combo) e.getSource()).getText(); + if (AUTH_TYPE_LABELS.containsValue(chosenPrivStr)) { + loop: for (String key : AUTH_TYPE_LABELS.keySet()) { + if (AUTH_TYPE_LABELS.get(key).equals(chosenPrivStr)) { + jcrPrivilege = key; + break loop; + } + } + } + + if (jcrPrivilege != null) { + descLbl.setText(AUTH_TYPE_DESC.get(jcrPrivilege)); + composite.layout(true, true); + } + } + }); + + // Compulsory + setControl(composite); + } + + public void modifyText(ModifyEvent event) { + String message = checkComplete(); + if (message != null) + setMessage(message, WizardPage.ERROR); + else { + setMessage("Complete", WizardPage.INFORMATION); + setPageComplete(true); + } + } + + /** @return error message or null if complete */ + protected String checkComplete() { + if (chosenUser == null) + return "Please choose a relevant group or user"; + else if (userAdmin.getRole(chosenUser.getName()) == null) + return "Please choose a relevant group or user"; + else if (jcrPrivilege == null) + return "Please choose a relevant JCR privilege"; + return null; + } + } + + private Label createBoldLabel(Composite parent, String value) { + Label label = new Label(parent, SWT.RIGHT); + label.setText(" " + value); + label.setFont(EclipseUiUtils.getBoldFont(parent)); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + return label; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java new file mode 100644 index 000000000..e6422a1e7 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import javax.jcr.Node; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.NodeLabelProvider; +import org.argeo.cms.ui.workbench.internal.jcr.SingleNodeAsTreeContentProvider; +import org.argeo.cms.ui.workbench.jcr.DefaultNodeEditor; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * List all childs of the current node and brings some browsing capabilities + * accross the repository + */ +public class ChildNodesPage extends FormPage { + // private final static Log log = LogFactory.getLog(ChildNodesPage.class); + + // business objects + private Node currentNode; + + // this page UI components + private SingleNodeAsTreeContentProvider nodeContentProvider; + private TreeViewer nodesViewer; + + public ChildNodesPage(FormEditor editor, String title, Node currentNode) { + super(editor, "ChildNodesPage", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + try { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("childNodesPageTitle")); + Composite body = form.getBody(); + GridLayout twt = new GridLayout(1, false); + twt.marginWidth = twt.marginHeight = 5; + body.setLayout(twt); + if (!currentNode.hasNodes()) { + managedForm.getToolkit().createLabel(body, + WorkbenchUiPlugin.getMessage("warningNoChildNode")); + } else { + nodeContentProvider = new SingleNodeAsTreeContentProvider(); + nodesViewer = createNodeViewer(body, nodeContentProvider); + nodesViewer.setInput(currentNode); + } + } catch (Exception e) { + throw new EclipseUiException( + "Unexpected error while creating child node page", e); + } + } + + protected TreeViewer createNodeViewer(Composite parent, + final ITreeContentProvider nodeContentProvider) { + + final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.BORDER); + Tree tree = tmpNodeViewer.getTree(); + tree.setLinesVisible(true); + tmpNodeViewer.getTree().setLayoutData(EclipseUiUtils.fillAll()); + tmpNodeViewer.setContentProvider(nodeContentProvider); + tmpNodeViewer.setLabelProvider(new NodeLabelProvider()); + tmpNodeViewer.addDoubleClickListener(new DClickListener()); + return tmpNodeViewer; + } + + public class DClickListener implements IDoubleClickListener { + + public void doubleClick(DoubleClickEvent event) { + if (event.getSelection() == null || event.getSelection().isEmpty()) + return; + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (obj instanceof Node) { + Node node = (Node) obj; + try { + GenericNodeEditorInput gnei = new GenericNodeEditorInput( + node); + WorkbenchUiPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .openEditor(gnei, DefaultNodeEditor.ID); + } catch (PartInitException pie) { + throw new EclipseUiException( + "Unexepected exception while opening node editor", + pie); + } + } + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java new file mode 100644 index 000000000..8d786e822 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** Dialog to change the current user password */ +public class ChooseNameDialog extends TitleAreaDialog { + private static final long serialVersionUID = 280139710002698692L; + private Text nameTxt; + + public ChooseNameDialog(Shell parentShell) { + super(parentShell); + setTitle("Choose name"); + } + + protected Point getInitialSize() { + return new Point(300, 250); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + Composite composite = new Composite(dialogarea, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + nameTxt = createLT(composite, "Name"); + + setMessage("Choose name", IMessageProvider.INFORMATION); + parent.pack(); + return composite; + } + + /** Creates label and text. */ + protected Text createLT(Composite parent, String label) { + new Label(parent, SWT.NONE).setText(label); + Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + return text; + } + + public String getName() { + return nameTxt.getText(); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/EmptyNodePage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/EmptyNodePage.java new file mode 100644 index 000000000..cd3f75648 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/EmptyNodePage.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * This page is only used at editor's creation time when current node has not + * yet been set + */ +public class EmptyNodePage extends FormPage { + // private final static Log log = LogFactory.getLog(EmptyNodePage.class); + + public EmptyNodePage(FormEditor editor, String title) { + super(editor, "Empty Page", title); + } + + protected void createFormContent(IManagedForm managedForm) { + try { + ScrolledForm form = managedForm.getForm(); + GridLayout twt = new GridLayout(1, false); + twt.marginWidth = twt.marginHeight = 0; + form.getBody().setLayout(twt); + Label lbl = new Label(form.getBody(), SWT.NONE); + lbl.setText("Empty page"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java new file mode 100644 index 000000000..c87127b89 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * An editor input based the JCR node object. + * */ + +public class GenericNodeEditorInput implements IEditorInput { + private final Node currentNode; + + // cache key properties at creation time to avoid Exception at recoring time + // when the session has been closed + private String path; + private String uid; + private String name; + + public GenericNodeEditorInput(Node currentNode) { + this.currentNode = currentNode; + try { + name = currentNode.getName(); + uid = currentNode.getIdentifier(); + path = currentNode.getPath(); + } catch (RepositoryException re) { + throw new EclipseUiException( + "unexpected error while getting node key values at creation time", + re); + } + } + + public Node getCurrentNode() { + return currentNode; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return name; + } + + public String getUid() { + return uid; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } + + public IPersistableElement getPersistable() { + return null; + } + + /** + * equals method based on UID that is unique within a workspace and path of + * the node, thus 2 shared node that have same UID as defined in the spec + * but 2 different pathes will open two distinct editors. + * + * TODO enhance this method to support multirepository and multiworkspace + * environments + */ + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + GenericNodeEditorInput other = (GenericNodeEditorInput) obj; + if (!getUid().equals(other.getUid())) + return false; + if (!getPath().equals(other.getPath())) + return false; + return true; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java new file mode 100644 index 000000000..ea1a64402 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.ListIterator; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * Main node editor page. Lists all properties of the current node and enable + * access and editing for some of them. + */ + +public class GenericNodePage extends FormPage implements WorkbenchConstants { + // private final static Log log = LogFactory.getLog(GenericNodePage.class); + + // local constants + private final static String JCR_PROPERTY_NAME = "jcr:name"; + + // Utils + protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT); + + // Main business Objects + private Node currentNode; + + // This page widgets + private FormToolkit tk; + private List modifyableProperties = new ArrayList(); + + public GenericNodePage(FormEditor editor, String title, Node currentNode) { + super(editor, "id", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + tk = managedForm.getToolkit(); + ScrolledForm form = managedForm.getForm(); + GridLayout twt = new GridLayout(3, false); + twt.marginWidth = twt.marginHeight = 5; + + form.getBody().setLayout(twt); + createPropertiesPart(form.getBody()); + } + + private void createPropertiesPart(Composite parent) { + try { + + PropertyIterator pi = currentNode.getProperties(); + + // Initializes form part + AbstractFormPart part = new AbstractFormPart() { + public void commit(boolean onSave) { + try { + if (onSave) { + ListIterator it = modifyableProperties + .listIterator(); + while (it.hasNext()) { + // we only support Text controls for the time + // being + Text curControl = (Text) it.next(); + String value = curControl.getText(); + currentNode.setProperty((String) curControl + .getData(JCR_PROPERTY_NAME), value); + } + + // We only commit when onSave = true, + // thus it is still possible to save after a tab + // change. + super.commit(onSave); + if (currentNode.getSession().hasPendingChanges()) + currentNode.getSession().save(); + } + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while saving properties", re); + } + } + }; + + while (pi.hasNext()) { + Property prop = pi.nextProperty(); + addPropertyLine(parent, part, prop); + } + + getManagedForm().addPart(part); + } catch (RepositoryException re) { + throw new EclipseUiException( + "Error during creation of network details section", re); + } + + } + + private void addPropertyLine(Composite parent, AbstractFormPart part, + Property prop) { + try { + tk.createLabel(parent, prop.getName()); + tk.createLabel(parent, + "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]"); + + if (prop.getDefinition().isProtected()) { + tk.createLabel(parent, formatReadOnlyPropertyValue(prop)); + } else + addModifyableValueWidget(parent, part, prop); + } catch (RepositoryException re) { + throw new EclipseUiException("Cannot get property " + prop, re); + } + } + + private String formatReadOnlyPropertyValue(Property prop) { + try { + String strValue; + + if (prop.getType() == PropertyType.BINARY) + strValue = ""; + else if (prop.isMultiple()) + strValue = Arrays.asList(prop.getValues()).toString(); + else if (prop.getType() == PropertyType.DATE) + strValue = timeFormatter.format(prop.getValue().getDate() + .getTime()); + else + strValue = prop.getValue().getString(); + + return strValue; + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while formatting read only property value", + re); + } + } + + private Control addModifyableValueWidget(Composite parent, + AbstractFormPart part, Property prop) { + GridData gd; + try { + if (prop.getType() == PropertyType.STRING && !prop.isMultiple()) { + Text txt = tk.createText(parent, prop.getString(), SWT.WRAP + | SWT.MULTI); + gd = new GridData(GridData.FILL_HORIZONTAL); + txt.setLayoutData(gd); + txt.addModifyListener(new ModifiedFieldListener(part)); + txt.setData(JCR_PROPERTY_NAME, prop.getName()); + modifyableProperties.add(txt); + } else { + // unsupported property type for editing, we create a read only + // label. + return tk + .createLabel(parent, formatReadOnlyPropertyValue(prop)); + } + return null; + } catch (RepositoryException re) { + throw new EclipseUiException( + "Unexpected error while formatting read only property value", + re); + } + + } + + private class ModifiedFieldListener implements ModifyListener { + private static final long serialVersionUID = 2117484480773434646L; + private AbstractFormPart formPart; + + public ModifiedFieldListener(AbstractFormPart generalPart) { + this.formPart = generalPart; + } + + public void modifyText(ModifyEvent e) { + formPart.markDirty(); + } + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java new file mode 100644 index 000000000..9e236524e --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Value; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.cms.ui.workbench.internal.jcr.PropertyLabelProvider; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.layout.TreeColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * Generic editor property page. Lists all properties of current node as a + * complex tree. TODO: enable editing + */ +public class GenericPropertyPage extends FormPage implements WorkbenchConstants { + // private final static Log log = + // LogFactory.getLog(GenericPropertyPage.class); + + // Main business Objects + private Node currentNode; + + public GenericPropertyPage(FormEditor editor, String title, Node currentNode) { + super(editor, "id", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("genericNodePageTitle")); + + Composite body = form.getBody(); + FillLayout layout = new FillLayout(); + layout.marginHeight = 5; + layout.marginWidth = 5; + body.setLayout(layout); + createComplexTree(body); + // TODO TreeColumnLayout triggers a scroll issue with the form: + // The inside body is always to big and a scroll bar is shown + // Composite tableCmp = new Composite(body, SWT.NO_FOCUS); + // createComplexTree(tableCmp); + } + + private TreeViewer createComplexTree(Composite parent) { + int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION; + Tree tree = new Tree(parent, style); + TreeColumnLayout tableColumnLayout = new TreeColumnLayout(); + + createColumn(tree, tableColumnLayout, "Property", SWT.LEFT, 200, 30); + createColumn(tree, tableColumnLayout, "Value(s)", SWT.LEFT, 300, 60); + createColumn(tree, tableColumnLayout, "Attributes", SWT.LEFT, 75, 0); + // Do not apply the treeColumnLayout it does not work yet + // parent.setLayout(tableColumnLayout); + + tree.setLinesVisible(true); + tree.setHeaderVisible(true); + + TreeViewer treeViewer = new TreeViewer(tree); + treeViewer.setContentProvider(new TreeContentProvider()); + treeViewer.setLabelProvider(new PropertyLabelProvider()); + treeViewer.setInput(currentNode); + treeViewer.expandAll(); + return treeViewer; + } + + private static TreeColumn createColumn(Tree parent, + TreeColumnLayout tableColumnLayout, String name, int style, + int width, int weight) { + TreeColumn column = new TreeColumn(parent, style); + column.setText(name); + column.setWidth(width); + column.setMoveable(true); + column.setResizable(true); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight, + width, true)); + return column; + } + + // + // private void createPropertiesPart(Composite parent) { + // try { + // + // PropertyIterator pi = currentNode.getProperties(); + // + // // Initializes form part + // AbstractFormPart part = new AbstractFormPart() { + // public void commit(boolean onSave) { + // try { + // if (onSave) { + // ListIterator it = modifyableProperties + // .listIterator(); + // while (it.hasNext()) { + // // we only support Text controls for the time + // // being + // Text curControl = (Text) it.next(); + // String value = curControl.getText(); + // currentNode.setProperty((String) curControl + // .getData(JCR_PROPERTY_NAME), value); + // } + // + // // We only commit when onSave = true, + // // thus it is still possible to save after a tab + // // change. + // super.commit(onSave); + // } + // } catch (RepositoryException re) { + // throw new EclipseUiException( + // "Unexpected error while saving properties", re); + // } + // } + // }; + // + // while (pi.hasNext()) { + // Property prop = pi.nextProperty(); + // addPropertyLine(parent, part, prop); + // } + // + // getManagedForm().addPart(part); + // } catch (RepositoryException re) { + // throw new EclipseUiException( + // "Error during creation of network details section", re); + // } + // + // } + // + // private void addPropertyLine(Composite parent, AbstractFormPart part, + // Property prop) { + // try { + // tk.createLabel(parent, prop.getName()); + // tk.createLabel(parent, + // "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]"); + // + // if (prop.getDefinition().isProtected()) { + // tk.createLabel(parent, formatReadOnlyPropertyValue(prop)); + // } else + // addModifyableValueWidget(parent, part, prop); + // } catch (RepositoryException re) { + // throw new EclipseUiException("Cannot get property " + prop, re); + // } + // } + // + // private String formatReadOnlyPropertyValue(Property prop) { + // try { + // String strValue; + // + // if (prop.getType() == PropertyType.BINARY) + // strValue = ""; + // else if (prop.isMultiple()) + // strValue = Arrays.asList(prop.getValues()).toString(); + // else if (prop.getType() == PropertyType.DATE) + // strValue = timeFormatter.format(prop.getValue().getDate() + // .getTime()); + // else + // strValue = prop.getValue().getString(); + // + // return strValue; + // } catch (RepositoryException re) { + // throw new EclipseUiException( + // "Unexpected error while formatting read only property value", + // re); + // } + // } + // + // private Control addModifyableValueWidget(Composite parent, + // AbstractFormPart part, Property prop) { + // GridData gd; + // try { + // if (prop.getType() == PropertyType.STRING) { + // Text txt = tk.createText(parent, prop.getString()); + // gd = new GridData(GridData.FILL_HORIZONTAL); + // txt.setLayoutData(gd); + // txt.addModifyListener(new ModifiedFieldListener(part)); + // txt.setData(JCR_PROPERTY_NAME, prop.getName()); + // modifyableProperties.add(txt); + // } else { + // // unsupported property type for editing, we create a read only + // // label. + // return tk + // .createLabel(parent, formatReadOnlyPropertyValue(prop)); + // } + // return null; + // } catch (RepositoryException re) { + // throw new EclipseUiException( + // "Unexpected error while formatting read only property value", + // re); + // } + // + // } + + // Multiple Value Model + // protected class MultipleValueItem { + // private int index; + // private Value value; + // + // public MultipleValueItem(int index, Value value) { + // this.index = index; + // this.value = value; + // } + // + // public int getIndex() { + // return index; + // } + // + // public Object getValue() { + // return value; + // } + // } + + private class TreeContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = -6162736530019406214L; + + public Object[] getElements(Object parent) { + Object[] props = null; + try { + + if (parent instanceof Node) { + Node node = (Node) parent; + PropertyIterator pi; + pi = node.getProperties(); + List propList = new ArrayList(); + while (pi.hasNext()) { + propList.add(pi.nextProperty()); + } + props = propList.toArray(); + } + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected exception while listing node properties", e); + } + return props; + } + + public Object getParent(Object child) { + return null; + } + + public Object[] getChildren(Object parent) { + Object[] result = null; + if (parent instanceof Property) { + Property prop = (Property) parent; + try { + + if (prop.isMultiple()) { + Value[] values = prop.getValues(); + // List list = new + // ArrayList(); + // for (int i = 0; i < values.length; i++) { + // MultipleValueItem mvi = new MultipleValueItem(i, + // values[i]); + // list.add(mvi); + // } + + return values; + } + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected error getting multiple values property.", + e); + } + } + return result; + } + + public boolean hasChildren(Object parent) { + try { + if (parent instanceof Property + && ((Property) parent).isMultiple()) { + return true; + } + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected exception while checking if property is multiple", + e); + } + return false; + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public void dispose() { + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ImportFileSystemWizard.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ImportFileSystemWizard.java new file mode 100644 index 000000000..a93dd5649 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ImportFileSystemWizard.java @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.nodetype.NodeType; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.eclipse.ui.specific.UploadFileWizardPage; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.Wizard; + +public class ImportFileSystemWizard extends Wizard { + private final static Log log = LogFactory + .getLog(ImportFileSystemWizard.class); + + private UploadFileWizardPage importPage; + private final Node folder; + + public ImportFileSystemWizard(Node folder) { + this.folder = folder; + setWindowTitle("Import from file system"); + } + + @Override + public void addPages() { + importPage = new UploadFileWizardPage(); + addPage(importPage); + setNeedsProgressMonitor(importPage.getNeedsProgressMonitor()); + } + + /** + * Called when the user click on 'Finish' in the wizard. The real upload to + * the JCR repository is done here. + */ + @Override + public boolean performFinish() { + + // Initialization + final String objectType = importPage.getObjectType(); + final String objectPath = importPage.getObjectPath(); + + // We do not display a progress bar for one file only + if (UploadFileWizardPage.FILE_ITEM_TYPE.equals(objectType)) { + // In Rap we must force the "real" upload of the file + // importPage.performFinish(); + try { + Node fileNode = folder.addNode(importPage.getObjectName(), + NodeType.NT_FILE); + Node resNode = fileNode.addNode(Property.JCR_CONTENT, + NodeType.NT_RESOURCE); + Binary binary = null; + InputStream is = null; + try { + is = importPage.getFileInputStream(); + binary = folder.getSession().getValueFactory() + .createBinary(is); + resNode.setProperty(Property.JCR_DATA, binary); + } finally { + if (binary != null) + binary.dispose(); + IOUtils.closeQuietly(is); + } + folder.getSession().save(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } else if (UploadFileWizardPage.FOLDER_ITEM_TYPE.equals(objectType)) { + if (objectPath == null || !new File(objectPath).exists()) { + ErrorFeedback.show("Directory " + objectPath + + " does not exist"); + return false; + } + + Boolean failed = false; + final File dir = new File(objectPath).getAbsoluteFile(); + final Long sizeB = directorySize(dir, 0l); + final Stats stats = new Stats(); + Long begin = System.currentTimeMillis(); + try { + getContainer().run(true, true, new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + try { + Integer sizeKB = (int) (sizeB / FileUtils.ONE_KB); + monitor.beginTask("", sizeKB); + importDirectory(folder, dir, monitor, stats); + monitor.done(); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException) e; + else + throw new EclipseUiException("Cannot import " + + objectPath, e); + } + } + }); + } catch (Exception e) { + ErrorFeedback.show("Cannot import " + objectPath, e); + failed = true; + } + + Long duration = System.currentTimeMillis() - begin; + Long durationS = duration / 1000l; + String durationStr = (durationS / 60) + " min " + (durationS % 60) + + " s"; + StringBuffer message = new StringBuffer("Imported\n"); + message.append(stats.fileCount).append(" files\n"); + message.append(stats.dirCount).append(" directories\n"); + message.append(FileUtils.byteCountToDisplaySize(stats.sizeB)); + if (failed) + message.append(" of planned ").append( + FileUtils.byteCountToDisplaySize(sizeB)); + message.append("\n"); + message.append("in ").append(durationStr).append("\n"); + if (failed) + MessageDialog.openError(getShell(), "Import failed", + message.toString()); + else + MessageDialog.openInformation(getShell(), "Import successful", + message.toString()); + + return true; + } + return false; + + } + + /** Recursively computes the size of the directory in bytes. */ + protected Long directorySize(File dir, Long currentSize) { + Long size = currentSize; + File[] files = dir.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + size = directorySize(file, size); + } else { + size = size + file.length(); + } + } + return size; + } + + /** + * Import recursively a directory and its content to the repository. + */ + protected void importDirectory(Node folder, File dir, + IProgressMonitor monitor, Stats stats) { + try { + File[] files = dir.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + Node childFolder = folder.addNode(file.getName(), + NodeType.NT_FOLDER); + importDirectory(childFolder, file, monitor, stats); + folder.getSession().save(); + stats.dirCount++; + } else { + Long fileSize = file.length(); + // we skip temporary files that are created by apps when a + // file is being edited. + // TODO : make this configurable. + if (file.getName().lastIndexOf('~') != file.getName() + .length() - 1) { + + monitor.subTask(file.getName() + " (" + + FileUtils.byteCountToDisplaySize(fileSize) + + ") " + file.getCanonicalPath()); + try { + Node fileNode = folder.addNode(file.getName(), + NodeType.NT_FILE); + Node resNode = fileNode.addNode( + Property.JCR_CONTENT, NodeType.NT_RESOURCE); + Binary binary = null; + try { + binary = folder + .getSession() + .getValueFactory() + .createBinary(new FileInputStream(file)); + resNode.setProperty(Property.JCR_DATA, binary); + } finally { + if (binary != null) + binary.dispose(); + } + folder.getSession().save(); + stats.fileCount++; + stats.sizeB = stats.sizeB + fileSize; + } catch (Exception e) { + log.warn("Import of " + + file + + " (" + + FileUtils + .byteCountToDisplaySize(fileSize) + + ") failed: " + e); + folder.getSession().refresh(false); + } + monitor.worked((int) (fileSize / FileUtils.ONE_KB)); + } + } + } + } catch (Exception e) { + throw new EclipseUiException("Cannot import " + dir + " to " + folder, + e); + } + } + + static class Stats { + public Long fileCount = 0l; + public Long dirCount = 0l; + public Long sizeB = 0l; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java new file mode 100644 index 000000000..5de33ff88 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +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/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java new file mode 100644 index 000000000..ccda09995 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * A canonical editor input based on a path to a node. In a multirepository + * environment, path can be enriched with Repository Alias and workspace + */ + +public class NodeEditorInput implements IEditorInput { + private final String path; + + public NodeEditorInput(String path) { + this.path = path; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return path; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java new file mode 100644 index 000000000..c1dc7fa0e --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Value; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +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.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * Display and edit a given node privilege. For the time being it is completely + * JackRabbit specific (and hardcoded for this) and will display an empty page + * if using any other implementation + */ +public class NodePrivilegesPage extends FormPage { + + private Node context; + + private TableViewer viewer; + + public NodePrivilegesPage(FormEditor editor, String title, Node context) { + super(editor, "NodePrivilegesPage", title); + this.context = context; + } + + protected void createFormContent(IManagedForm managedForm) { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin + .getMessage("nodeRightsManagementPageTitle")); + FillLayout layout = new FillLayout(); + layout.marginHeight = 5; + layout.marginWidth = 5; + form.getBody().setLayout(layout); + if (isJackRabbit()) + createRightsPart(form.getBody()); + } + + /** Creates the authorization part */ + protected void createRightsPart(Composite parent) { + Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + table.setLinesVisible(true); + table.setHeaderVisible(true); + viewer = new TableViewer(table); + + // Group / user name + TableViewerColumn column = createTableViewerColumn(viewer, + "User/Group Name", 280); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -2290781173498395973L; + + public String getText(Object element) { + Node node = (Node) element; + try { + if (node.hasProperty("rep:principalName")) + return node.getProperty("rep:principalName") + .getString(); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to retrieve " + + "principal name on " + node, e); + } + return ""; + } + + public Image getImage(Object element) { + return null; + } + }); + + // Privileges + column = createTableViewerColumn(viewer, "Assigned privileges", 300); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -2290781173498395973L; + private String propertyName = "rep:privileges"; + + public String getText(Object element) { + Node node = (Node) element; + try { + if (node.hasProperty(propertyName)) { + String separator = ", "; + Value[] langs = node.getProperty(propertyName) + .getValues(); + StringBuilder builder = new StringBuilder(); + for (Value val : langs) { + String currStr = val.getString(); + builder.append(currStr).append(separator); + } + if (builder.lastIndexOf(separator) >= 0) + return builder.substring(0, builder.length() + - separator.length()); + else + return builder.toString(); + + } + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to retrieve " + + "privileges on " + node, e); + } + return ""; + } + + public Image getImage(Object element) { + return null; + } + }); + + // Relevant node + column = createTableViewerColumn(viewer, "Relevant node", 300); + column.setLabelProvider(new ColumnLabelProvider() { + /** + * + */ + private static final long serialVersionUID = 4245522992038244849L; + + public String getText(Object element) { + Node node = (Node) element; + try { + return node.getParent().getParent().getPath(); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable get path for " + node, + e); + } + } + + public Image getImage(Object element) { + return null; + } + }); + + viewer.setContentProvider(new RightsContentProvider()); + viewer.setInput(getEditorSite()); + } + + protected TableViewerColumn createTableViewerColumn(TableViewer viewer, + String title, int bound) { + final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, + SWT.NONE); + final TableColumn column = viewerColumn.getColumn(); + column.setText(title); + column.setWidth(bound); + column.setResizable(true); + column.setMoveable(true); + return viewerColumn; + } + + private class RightsContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -7631476348552802706L; + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + // TODO JackRabbit specific retrieval of authorization. Clean and + // generalize + public Object[] getElements(Object inputElement) { + try { + List privs = new ArrayList(); + + Node currNode = context; + String currPath = currNode.getPath(); + + loop: while (true) { + if (currNode.hasNode("rep:policy")) { + NodeIterator nit = currNode.getNode("rep:policy") + .getNodes(); + while (nit.hasNext()) { + Node currPrivNode = nit.nextNode(); + if (currPrivNode.getName().startsWith("allow")) + privs.add(currPrivNode); + } + } + if ("/".equals(currPath)) + break loop; + else { + currNode = currNode.getParent(); + currPath = currNode.getPath(); + } + } + + // AccessControlManager acm = context.getSession() + // .getAccessControlManager(); + // AccessControlPolicyIterator acpi = acm + // .getApplicablePolicies(context.getPath()); + // + // List acps = new + // ArrayList(); + // try { + // while (true) { + // Object obj = acpi.next(); + // acps.add((AccessControlPolicy) obj); + // } + // } catch (Exception e) { + // // No more elements + // } + // + // AccessControlList acl = ((AccessControlList) acps.get(0)); + // AccessControlEntry[] entries = acl.getAccessControlEntries(); + + return privs.toArray(); + } catch (Exception e) { + throw new EclipseUiException( + "Cannot retrieve authorization for " + context, e); + } + } + } + + // simply check if we are using jackrabbit without adding code dependencies + private boolean isJackRabbit() { + try { + String cname = context.getSession().getClass().getName(); + return cname.startsWith("org.apache.jackrabbit"); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Cannot check JCR implementation used on " + context, e); + } + } + +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java new file mode 100644 index 000000000..4e3d9932a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Value; +import javax.jcr.nodetype.NodeType; +import javax.jcr.version.Version; +import javax.jcr.version.VersionHistory; +import javax.jcr.version.VersionIterator; +import javax.jcr.version.VersionManager; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.cms.ui.workbench.internal.jcr.FullVersioningTreeContentProvider; +import org.argeo.cms.ui.workbench.internal.jcr.GenericNodeDoubleClickListener; +import org.argeo.cms.ui.workbench.internal.jcr.VersionLabelProvider; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.PropertyDiff; +import org.argeo.jcr.VersionDiff; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.forms.widgets.TableWrapData; +import org.eclipse.ui.forms.widgets.TableWrapLayout; + +/** + * Offers two main sections : one to display a text area with a summary of all + * variations between a version and its predecessor and one tree view that + * enable browsing + * */ +public class NodeVersionHistoryPage extends FormPage implements + WorkbenchConstants { + // private final static Log log = LogFactory + // .getLog(NodeVersionHistoryPage.class); + + // Utils + protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT); + + // business objects + private Node currentNode; + + // this page UI components + private FullVersioningTreeContentProvider nodeContentProvider; + private TreeViewer nodesViewer; + private FormToolkit tk; + + public NodeVersionHistoryPage(FormEditor editor, String title, + Node currentNode) { + super(editor, "NodeVersionHistoryPage", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("nodeVersionHistoryPageTitle")); + tk = managedForm.getToolkit(); + GridLayout twt = new GridLayout(1, false); + twt.marginWidth = twt.marginHeight = 5; + Composite body = form.getBody(); + body.setLayout(twt); + + try { + if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) { + tk.createLabel(body, + WorkbenchUiPlugin.getMessage("warningUnversionableNode")); + } else { + createHistorySection(form.getBody()); + createTreeSection(form.getBody()); + } + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected error while checking if node is versionable", e); + } + } + + protected void createTreeSection(Composite parent) { + // Section Layout & MetaData + Section section = tk.createSection(parent, Section.TWISTIE); + section.setLayoutData(new GridData(GridData.FILL_BOTH)); + section.setText(WorkbenchUiPlugin.getMessage("versionTreeSectionTitle")); + + // Section Body + Composite body = tk.createComposite(section, SWT.FILL); + // WARNING : 2 following lines are compulsory or body won't be + // displayed. + body.setLayout(new GridLayout()); + section.setClient(body); + + body.setLayoutData(new GridData(GridData.FILL_BOTH)); + section.setExpanded(true); + + nodeContentProvider = new FullVersioningTreeContentProvider(); + nodesViewer = createNodeViewer(body, nodeContentProvider); + nodesViewer.setInput(currentNode); + } + + protected TreeViewer createNodeViewer(Composite parent, + final ITreeContentProvider nodeContentProvider) { + + final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI); + + tmpNodeViewer.getTree().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + tmpNodeViewer.setContentProvider(nodeContentProvider); + tmpNodeViewer.setLabelProvider(new VersionLabelProvider()); + tmpNodeViewer + .addDoubleClickListener(new GenericNodeDoubleClickListener( + tmpNodeViewer)); + return tmpNodeViewer; + } + + protected void createHistorySection(Composite parent) { + + // Section Layout + Section section = tk.createSection(parent, Section.TWISTIE); + section.setLayoutData(new GridData(TableWrapData.FILL_GRAB)); + TableWrapLayout twt = new TableWrapLayout(); + section.setLayout(twt); + + // Set title of the section + section.setText(WorkbenchUiPlugin + .getMessage("versionHistorySectionTitle")); + + final Text styledText = tk.createText(section, "", SWT.FULL_SELECTION + | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); + styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + section.setClient(styledText); + refreshHistory(styledText); + styledText.setEditable(false); + section.setExpanded(false); + + AbstractFormPart part = new AbstractFormPart() { + public void commit(boolean onSave) { + } + + public void refresh() { + super.refresh(); + refreshHistory(styledText); + } + }; + getManagedForm().addPart(part); + } + + protected void refreshHistory(Text styledText) { + try { + List lst = listHistoryDiff(); + StringBuffer main = new StringBuffer(""); + + for (int i = lst.size() - 1; i >= 0; i--) { + if (i == 0) + main.append("Creation ("); + else + main.append("Update " + i + " ("); + + if (lst.get(i).getUserId() != null) + main.append("UserId : " + lst.get(i).getUserId()); + + if (lst.get(i).getUserId() != null + && lst.get(i).getUpdateTime() != null) + main.append(", "); + + if (lst.get(i).getUpdateTime() != null) + main.append("Date : " + + timeFormatter.format(lst.get(i).getUpdateTime() + .getTime()) + ")\n"); + + StringBuffer buf = new StringBuffer(""); + Map diffs = lst.get(i).getDiffs(); + for (String prop : diffs.keySet()) { + PropertyDiff pd = diffs.get(prop); + // String propName = pd.getRelPath(); + Value refValue = pd.getReferenceValue(); + Value newValue = pd.getNewValue(); + String refValueStr = ""; + String newValueStr = ""; + + if (refValue != null) { + if (refValue.getType() == PropertyType.DATE) { + refValueStr = timeFormatter.format(refValue + .getDate().getTime()); + } else + refValueStr = refValue.getString(); + } + if (newValue != null) { + if (newValue.getType() == PropertyType.DATE) { + newValueStr = timeFormatter.format(newValue + .getDate().getTime()); + } else + newValueStr = newValue.getString(); + } + + if (pd.getType() == PropertyDiff.MODIFIED) { + buf.append(prop).append(": "); + buf.append(refValueStr); + buf.append(" > "); + buf.append(newValueStr); + buf.append("\n"); + } else if (pd.getType() == PropertyDiff.ADDED + && !"".equals(newValueStr)) { + // we don't list property that have been added with an + // empty string as value + buf.append(prop).append(": "); + buf.append(" + "); + buf.append(newValueStr); + buf.append("\n"); + } else if (pd.getType() == PropertyDiff.REMOVED) { + buf.append(prop).append(": "); + buf.append(" - "); + buf.append(refValueStr); + buf.append("\n"); + } + } + buf.append("\n"); + main.append(buf); + } + styledText.setText(main.toString()); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot generate history for node", e); + } + + } + + public List listHistoryDiff() { + try { + List res = new ArrayList(); + VersionManager versionManager = currentNode.getSession() + .getWorkspace().getVersionManager(); + VersionHistory versionHistory = versionManager + .getVersionHistory(currentNode.getPath()); + + VersionIterator vit = versionHistory.getAllLinearVersions(); + while (vit.hasNext()) { + Version version = vit.nextVersion(); + Node node = version.getFrozenNode(); + Version predecessor = null; + try { + predecessor = version.getLinearPredecessor(); + } catch (Exception e) { + // no predecessor seems to throw an exception even if it + // shouldn't... + } + if (predecessor == null) {// original + } else { + Map diffs = JcrUtils.diffProperties( + predecessor.getFrozenNode(), node); + if (!diffs.isEmpty()) { + String lastUserName = null; + Calendar lastUpdate = null; + try { + if (currentNode + .isNodeType(NodeType.MIX_LAST_MODIFIED)) { + lastUserName = node.getProperty( + Property.JCR_LAST_MODIFIED_BY) + .getString(); + lastUpdate = node.getProperty( + Property.JCR_LAST_MODIFIED).getDate(); + } else + lastUpdate = version.getProperty( + Property.JCR_CREATED).getDate(); + + } catch (Exception e) { + // Silent that info is optional + } + VersionDiff vd = new VersionDiff(lastUserName, + lastUpdate, diffs); + res.add(vd); + } + } + } + return res; + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot generate history for node "); + } + + } + + @Override + public void setActive(boolean active) { + super.setActive(active); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java new file mode 100644 index 000000000..3740debe6 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * An editor input based on three strings define a node : + *
    + *
  • complete path to the node
  • + *
  • the workspace name
  • + *
  • the repository alias
  • + *
+ * In a single workspace and/or repository environment, name and alias can be + * null. + * + * Note : unused for the time being. + */ + +public class StringNodeEditorInput implements IEditorInput { + private final String path; + private final String repositoryAlias; + private final String workspaceName; + + /** + * In order to implement a generic explorer that supports remote and multi + * workspaces repositories, node path can be detailed by these strings. + * + * @param repositoryAlias + * : can be null + * @param workspaceName + * : can be null + * @param path + */ + public StringNodeEditorInput(String repositoryAlias, String workspaceName, + String path) { + this.path = path; + this.repositoryAlias = repositoryAlias; + this.workspaceName = workspaceName; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return path; + } + + public String getRepositoryAlias() { + return repositoryAlias; + } + + public String getWorkspaceName() { + return workspaceName; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + StringNodeEditorInput other = (StringNodeEditorInput) obj; + + if (!path.equals(other.getPath())) + return false; + + String own = other.getWorkspaceName(); + if ((workspaceName == null && own != null) + || (workspaceName != null && (own == null || !workspaceName + .equals(own)))) + return false; + + String ora = other.getRepositoryAlias(); + if ((repositoryAlias == null && ora != null) + || (repositoryAlias != null && (ora == null || !repositoryAlias + .equals(ora)))) + return false; + + return true; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java new file mode 100644 index 000000000..cac43b1b0 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java @@ -0,0 +1,58 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import org.argeo.cms.CmsException; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IStartup; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; + +/** Manage transaction and part refresh while updating the security model */ +public class PartStateChanged implements IPartListener, IStartup { + // private final static Log log = LogFactory.getLog(PartStateChanged.class); + // private IContextActivation contextActivation; + + @Override + public void earlyStartup() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + try { + IWorkbenchPage iwp = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + if (iwp != null) + iwp.addPartListener(new PartStateChanged()); + } catch (Exception e) { + throw new CmsException( + "Error while registering the PartStateChangedListener", + e); + } + } + }); + } + + @Override + public void partActivated(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partClosed(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partOpened(IWorkbenchPart part) { + // Nothing to do + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java new file mode 100644 index 000000000..ebb45e23a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java @@ -0,0 +1,48 @@ +/* + * Argeo Connect - Data management and communications + * Copyright (C) 2012 Argeo GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with software covered by the terms of the Eclipse Public License, the + * licensors of this Program grant you additional permission to convey the + * resulting work. Corresponding Source for a non-source form of such a + * combination shall include the source code for the parts of such software + * which are used as well as that of the covered work. + */ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; + +/** Shared icons that must be declared programmatically . */ +public class SecurityAdminImages { + private final static String PREFIX = "icons/"; + + public final static ImageDescriptor ICON_REMOVE_DESC = WorkbenchUiPlugin + .getImageDescriptor(PREFIX + "remove.gif"); + public final static ImageDescriptor ICON_USER_DESC = WorkbenchUiPlugin + .getImageDescriptor(PREFIX + "user.gif"); + + public final static Image ICON_USER = ICON_USER_DESC.createImage(); + public final static Image ICON_GROUP = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "users.gif").createImage(); + public final static Image ICON_ROLE = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "role.gif").createImage(); + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java new file mode 100644 index 000000000..96b984a1d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java @@ -0,0 +1,32 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTransactionProvider; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.services.ISourceProviderService; + +/** First effort to centralize back end methods used by the user admin UI */ +public class UiAdminUtils { + /* + * INTERNAL METHODS: Below methods are meant to stay here and are not part + * of a potential generic backend to manage the useradmin + */ + /** Easily notify the ActiveWindow that the transaction had a state change */ + public final static void notifyTransactionStateChange( + UserTransaction userTransaction) { + try { + IWorkbenchWindow aww = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + ISourceProviderService sourceProviderService = (ISourceProviderService) aww + .getService(ISourceProviderService.class); + UserTransactionProvider esp = (UserTransactionProvider) sourceProviderService + .getSourceProvider(UserTransactionProvider.TRANSACTION_STATE); + esp.fireTransactionStateChange(); + } catch (Exception e) { + throw new CmsException("Unable to begin transaction", e); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java new file mode 100644 index 000000000..e51d69048 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java @@ -0,0 +1,27 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import org.eclipse.swt.widgets.Display; +import org.osgi.service.useradmin.UserAdminEvent; +import org.osgi.service.useradmin.UserAdminListener; + +/** Convenience class to insure the call to refresh is done in the UI thread */ +public abstract class UiUserAdminListener implements UserAdminListener { + + private final Display display; + + public UiUserAdminListener(Display display) { + this.display = display; + } + + @Override + public void roleChanged(final UserAdminEvent event) { + display.asyncExec(new Runnable() { + @Override + public void run() { + roleChangedToUiThread(event); + } + }); + } + + public abstract void roleChangedToUiThread(UserAdminEvent event); +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java new file mode 100644 index 000000000..2f59e8642 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java @@ -0,0 +1,77 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import java.util.ArrayList; +import java.util.List; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.osgi.service.useradmin.UserAdminEvent; +import org.osgi.service.useradmin.UserAdminListener; + +/** Centralise interaction with the UserAdmin in this bundle */ +public class UserAdminWrapper extends + org.argeo.cms.util.useradmin.UserAdminWrapper { + + // First effort to simplify UX while managing users and groups + public final static boolean COMMIT_ON_SAVE = true; + + // Registered listeners + List listeners = new ArrayList(); + + /** + * Starts a transaction if necessary. Should always been called together + * with {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once + * the security model changes have been performed. + */ + public UserTransaction beginTransactionIfNeeded() { + try { + UserTransaction userTransaction = getUserTransaction(); + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) { + userTransaction.begin(); + // UiAdminUtils.notifyTransactionStateChange(userTransaction); + } + return userTransaction; + } catch (Exception e) { + throw new CmsException("Unable to begin transaction", e); + } + } + + /** + * Depending on the current application configuration, it will either commit + * the current transaction or throw a notification that the transaction + * state has changed (In the later case, it must be called from the UI + * thread). + */ + public void commitOrNotifyTransactionStateChange() { + try { + UserTransaction userTransaction = getUserTransaction(); + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + return; + + if (UserAdminWrapper.COMMIT_ON_SAVE) + userTransaction.commit(); + else + UiAdminUtils.notifyTransactionStateChange(userTransaction); + } catch (Exception e) { + throw new CmsException("Unable to clean transaction", e); + } + } + + // TODO implement safer mechanism + public void addListener(UserAdminListener userAdminListener) { + if (!listeners.contains(userAdminListener)) + listeners.add(userAdminListener); + } + + public void removeListener(UserAdminListener userAdminListener) { + if (listeners.contains(userAdminListener)) + listeners.remove(userAdminListener); + } + + public void notifyListeners(UserAdminEvent event) { + for (UserAdminListener listener : listeners) + listener.roleChanged(event); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UsersImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UsersImages.java new file mode 100644 index 000000000..bf739a7f6 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UsersImages.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** Specific users icons. TODO centralize and use an image registry */ +public class UsersImages { + private final static String PREFIX = "icons/"; + + public final static Image ICON_USER = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "user.gif").createImage(); + public final static Image ICON_GROUP = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "users.gif").createImage(); + public final static Image ICON_ROLE = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "role.gif").createImage(); +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UsersUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UsersUtils.java new file mode 100644 index 000000000..7edfb8118 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UsersUtils.java @@ -0,0 +1,100 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import java.security.AccessController; +import java.util.List; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.osgi.useradmin.LdifName; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** Utility methods to manage user concepts in the ui.workbench bundle */ +public class UsersUtils { + // TODO this constant is defined in the CMS + public final static String ROLES_BASEDN = "ou=roles,ou=node"; + + public final static boolean isCurrentUser(User user) { + String userName = getProperty(user, LdifName.dn.name()); + try { + LdapName selfUserName = getLdapName(); + LdapName userLdapName = new LdapName(userName); + if (userLdapName.equals(selfUserName)) + return true; + else + return false; + } catch (InvalidNameException e) { + throw new EclipseUiException("User " + user + " has an unvalid dn: " + + userName, e); + } + } + + public final static LdapName getLdapName() { + Subject subject = Subject.getSubject(AccessController.getContext()); + String name = subject.getPrincipals(X500Principal.class).iterator() + .next().toString(); + LdapName dn; + try { + dn = new LdapName(name); + } catch (InvalidNameException e) { + throw new EclipseUiException("Invalid user dn " + name, e); + } + return dn; + } + + public final static String getCommonName(User user) { + return getProperty(user, LdifName.cn.name()); + } + + /** Simply retrieves a display name of the relevant domain */ + public final static String getDomainName(User user) { + String dn = (String) user.getProperties().get(LdifName.dn.name()); + if (dn.endsWith(ROLES_BASEDN)) + return "System roles"; + try { + LdapName name; + name = new LdapName(dn); + List rdns = name.getRdns(); + String dname = null; + int i = 0; + loop: while (i < rdns.size()) { + Rdn currrRdn = rdns.get(i); + if (!"dc".equals(currrRdn.getType())) + break loop; + else { + String currVal = (String) currrRdn.getValue(); + dname = dname == null ? currVal : currVal + "." + dname; + } + i++; + } + return dname; + } catch (InvalidNameException e) { + throw new EclipseUiException("Unable to get domain name for " + dn, e); + } + } + + public final static String getProperty(Role role, String key) { + Object obj = role.getProperties().get(key); + if (obj != null) + return (String) obj; + else + return ""; + } + + /* + * INTERNAL METHODS: Below methods are meant to stay here and are not part + * of a potential generic backend to manage the useradmin + */ + public final static boolean notNull(String string) { + if (string == null) + return false; + else + return !"".equals(string.trim()); + } + +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java new file mode 100644 index 000000000..16128b8a4 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditorInput; +import org.argeo.cms.util.useradmin.UserAdminUtils; +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.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Delete the selected groups */ +public class DeleteGroups extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".deleteGroups"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + @SuppressWarnings("unchecked") + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection.isEmpty()) + return null; + + List groups = new ArrayList(); + Iterator it = ((IStructuredSelection) selection).iterator(); + StringBuilder builder = new StringBuilder(); + while (it.hasNext()) { + Group currGroup = it.next(); + String groupName = UserAdminUtils.getUsername(currGroup); + // TODO add checks + builder.append(groupName).append("; "); + groups.add(currGroup); + } + + if (!MessageDialog.openQuestion(HandlerUtil.getActiveShell(event), + "Delete Groups", + "Are you sure that you " + "want to delete these groups?\n" + + builder.substring(0, builder.length() - 2))) + return null; + + userAdminWrapper.beginTransactionIfNeeded(); + UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); + IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage(); + for (Group group : groups) { + String groupName = group.getName(); + // TODO find a way to close the editor cleanly if opened. Cannot be + // done through the UserAdminListeners, it causes a + // java.util.ConcurrentModificationException because disposing the + // editor unregisters and disposes the listener + IEditorPart part = iwp.findEditor(new UserEditorInput(groupName)); + if (part != null) + iwp.closeEditor(part, false); + userAdmin.removeRole(groupName); + } + userAdminWrapper.commitOrNotifyTransactionStateChange(); + + // Update the view + for (Group group : groups) { + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_REMOVED, group)); + } + + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java new file mode 100644 index 000000000..d2c34b55d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditorInput; +import org.argeo.cms.util.useradmin.UserAdminUtils; +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.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Delete the selected users */ +public class DeleteUsers extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".deleteUsers"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + @SuppressWarnings("unchecked") + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection.isEmpty()) + return null; + + Iterator it = ((IStructuredSelection) selection).iterator(); + List users = new ArrayList(); + StringBuilder builder = new StringBuilder(); + + while (it.hasNext()) { + User currUser = it.next(); + String userName = UserAdminUtils.getUsername(currUser); + if (UserAdminUtils.isCurrentUser(currUser)) { + MessageDialog.openError(HandlerUtil.getActiveShell(event), + "Deletion forbidden", + "You cannot delete your own user this way."); + return null; + } + builder.append(userName).append("; "); + users.add(currUser); + } + + if (!MessageDialog.openQuestion( + HandlerUtil.getActiveShell(event), + "Delete Users", + "Are you sure that you want to delete these users?\n" + + builder.substring(0, builder.length() - 2))) + return null; + + userAdminWrapper.beginTransactionIfNeeded(); + UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); + IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage(); + + for (User user : users) { + String userName = user.getName(); + // TODO find a way to close the editor cleanly if opened. Cannot be + // done through the UserAdminListeners, it causes a + // java.util.ConcurrentModificationException because disposing the + // editor unregisters and disposes the listener + IEditorPart part = iwp.findEditor(new UserEditorInput(userName)); + if (part != null) + iwp.closeEditor(part, false); + userAdmin.removeRole(userName); + } + userAdminWrapper.commitOrNotifyTransactionStateChange(); + + for (User user : users) { + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_REMOVED, user)); + } + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java new file mode 100644 index 000000000..30483ae45 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import org.argeo.cms.ui.workbench.internal.useradmin.parts.GroupsView; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UsersView; +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.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Retrieve the active view or editor and call forceRefresh method if defined */ +public class ForceRefresh extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow iww = HandlerUtil.getActiveWorkbenchWindow(event); + if (iww == null) + return null; + IWorkbenchPage activePage = iww.getActivePage(); + IWorkbenchPart part = activePage.getActivePart(); + if (part instanceof UsersView) + ((UsersView) part).refresh(); + else if (part instanceof GroupsView) + ((GroupsView) part).refresh(); + return null; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java new file mode 100644 index 000000000..48f0016e3 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import java.util.Dictionary; +import java.util.Map; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.argeo.osgi.useradmin.UserAdminConf; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Create a new group */ +public class NewGroup extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newGroup"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + NewGroupWizard newGroupWizard = new NewGroupWizard(); + newGroupWizard.setWindowTitle("Group creation"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), newGroupWizard); + dialog.open(); + return null; + } + + private class NewGroupWizard extends Wizard { + + // Pages + private MainGroupInfoWizardPage mainGroupInfo; + + // UI fields + private Text dNameTxt, commonNameTxt, descriptionTxt; + private Combo baseDnCmb; + + public NewGroupWizard() { + } + + @Override + public void addPages() { + mainGroupInfo = new MainGroupInfoWizardPage(); + addPage(mainGroupInfo); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public boolean performFinish() { + if (!canFinish()) + return false; + String commonName = commonNameTxt.getText(); + try { + userAdminWrapper.beginTransactionIfNeeded(); + String dn = getDn(commonName); + Group group = (Group) userAdminWrapper.getUserAdmin() + .createRole(dn, Role.GROUP); + Dictionary props = group.getProperties(); + String descStr = descriptionTxt.getText(); + if (EclipseUiUtils.notEmpty(descStr)) + props.put(LdifName.description.name(), descStr); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CREATED, group)); + return true; + } catch (Exception e) { + ErrorFeedback.show("Cannot create new group " + commonName, e); + return false; + } + } + + private class MainGroupInfoWizardPage extends WizardPage implements + FocusListener, ArgeoNames { + private static final long serialVersionUID = -3150193365151601807L; + + public MainGroupInfoWizardPage() { + super("Main"); + setTitle("General information"); + setMessage("Please choose a domain, provide a common name " + + "and a free description"); + } + + @Override + public void createControl(Composite parent) { + Composite bodyCmp = new Composite(parent, SWT.NONE); + setControl(bodyCmp); + bodyCmp.setLayout(new GridLayout(2, false)); + + dNameTxt = EclipseUiUtils.createGridLT(bodyCmp, + "Distinguished name"); + dNameTxt.setEnabled(false); + + baseDnCmb = createGridLC(bodyCmp, "Base DN"); + // Initialise before adding the listener to avoid NPE + initialiseDnCmb(baseDnCmb); + baseDnCmb.addFocusListener(this); + + commonNameTxt = EclipseUiUtils.createGridLT(bodyCmp, + "Common name"); + commonNameTxt.addFocusListener(this); + + Label descLbl = new Label(bodyCmp, SWT.LEAD); + descLbl.setText("Description"); + descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, + false)); + descriptionTxt = new Text(bodyCmp, SWT.LEAD | SWT.MULTI + | SWT.WRAP | SWT.BORDER); + descriptionTxt.setLayoutData(EclipseUiUtils.fillAll()); + descriptionTxt.addFocusListener(this); + + // Initialize buttons + setPageComplete(false); + getContainer().updateButtons(); + } + + @Override + public void focusLost(FocusEvent event) { + String name = commonNameTxt.getText(); + if (EclipseUiUtils.isEmpty(name)) + dNameTxt.setText(""); + else + dNameTxt.setText(getDn(name)); + + String message = checkComplete(); + if (message != null) { + setMessage(message, WizardPage.ERROR); + setPageComplete(false); + } else { + setMessage("Complete", WizardPage.INFORMATION); + setPageComplete(true); + } + getContainer().updateButtons(); + } + + @Override + public void focusGained(FocusEvent event) { + } + + /** @return the error message or null if complete */ + protected String checkComplete() { + String name = commonNameTxt.getText(); + + if (name.trim().equals("")) + return "Common name must not be empty"; + Role role = userAdminWrapper.getUserAdmin() + .getRole(getDn(name)); + if (role != null) + return "Group " + name + " already exists"; + return null; + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) + if (baseDnCmb.getSelectionIndex() == -1) + baseDnCmb.setFocus(); + else + commonNameTxt.setFocus(); + } + } + + private Map getDns() { + return userAdminWrapper.getKnownBaseDns(true); + } + + private String getDn(String cn) { + Map dns = getDns(); + String bdn = baseDnCmb.getText(); + if (EclipseUiUtils.notEmpty(bdn)) { + Dictionary props = UserAdminConf.uriAsProperties(dns + .get(bdn)); + String dn = LdifName.cn.name() + "=" + cn + "," + + UserAdminConf.groupBase.getValue(props) + "," + bdn; + return dn; + } + return null; + } + + private void initialiseDnCmb(Combo combo) { + Map dns = userAdminWrapper.getKnownBaseDns(true); + if (dns.isEmpty()) + throw new CmsException( + "No writable base dn found. Cannot create group"); + combo.setItems(dns.keySet().toArray(new String[0])); + if (dns.size() == 1) + combo.select(0); + } + } + + private Combo createGridLC(Composite parent, String label) { + Label lbl = new Label(parent, SWT.LEAD); + lbl.setText(label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY); + combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return combo; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java new file mode 100644 index 000000000..c259153f6 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import java.util.Dictionary; +import java.util.List; +import java.util.Map; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.argeo.osgi.useradmin.UserAdminConf; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Open a wizard that enables creation of a new user. */ +public class NewUser extends AbstractHandler { + /** + * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}. + * Thanks to this tip. + */ + public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; + // private final static Log log = LogFactory.getLog(NewUser.class); + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newUser"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + NewUserWizard newUserWizard = new NewUserWizard(); + newUserWizard.setWindowTitle("User creation"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), newUserWizard); + dialog.open(); + return null; + } + + private class NewUserWizard extends Wizard { + + // pages + private MainUserInfoWizardPage mainUserInfo; + + // End user fields + private Text dNameTxt, usernameTxt, firstNameTxt, lastNameTxt, + primaryMailTxt, pwd1Txt, pwd2Txt; + private Combo baseDnCmb; + + public NewUserWizard() { + + } + + @Override + public void addPages() { + mainUserInfo = new MainUserInfoWizardPage(); + addPage(mainUserInfo); + String message = "Default wizard that also eases user creation tests:\n " + + "Mail and last name are automatically " + + "generated form the uid. Password are defauted to 'demo'."; + mainUserInfo.setMessage(message, WizardPage.WARNING); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public boolean performFinish() { + if (!canFinish()) + return false; + String username = mainUserInfo.getUsername(); + userAdminWrapper.beginTransactionIfNeeded(); + try { + User user = (User) userAdminWrapper.getUserAdmin().createRole( + getDn(username), Role.USER); + + Dictionary props = user.getProperties(); + + String lastNameStr = lastNameTxt.getText(); + if (EclipseUiUtils.notEmpty(lastNameStr)) + props.put(LdifName.sn.name(), lastNameStr); + + String firstNameStr = firstNameTxt.getText(); + if (EclipseUiUtils.notEmpty(firstNameStr)) + props.put(LdifName.givenName.name(), firstNameStr); + + String cn = UserAdminUtils.buildDefaultCn(firstNameStr, + lastNameStr); + if (EclipseUiUtils.notEmpty(cn)) + props.put(LdifName.cn.name(), cn); + + String mailStr = primaryMailTxt.getText(); + if (EclipseUiUtils.notEmpty(mailStr)) + props.put(LdifName.mail.name(), mailStr); + + char[] password = mainUserInfo.getPassword(); + user.getCredentials().put(null, password); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CREATED, user)); + return true; + } catch (Exception e) { + ErrorFeedback.show("Cannot create new user " + username, e); + return false; + } + } + + private class MainUserInfoWizardPage extends WizardPage implements + ModifyListener, ArgeoNames { + private static final long serialVersionUID = -3150193365151601807L; + + public MainUserInfoWizardPage() { + super("Main"); + setTitle("Required Information"); + } + + @Override + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + dNameTxt = EclipseUiUtils.createGridLT(composite, + "Distinguished name", this); + dNameTxt.setEnabled(false); + + baseDnCmb = createGridLC(composite, "Base DN"); + initialiseDnCmb(baseDnCmb); + baseDnCmb.addModifyListener(this); + baseDnCmb.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = -1435351236582736843L; + + @Override + public void modifyText(ModifyEvent event) { + String name = usernameTxt.getText(); + dNameTxt.setText(getDn(name)); + } + }); + + usernameTxt = EclipseUiUtils.createGridLT(composite, + "Local ID", this); + usernameTxt.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = -1435351236582736843L; + + @Override + public void modifyText(ModifyEvent event) { + String name = usernameTxt.getText(); + if (name.trim().equals("")) { + dNameTxt.setText(""); + lastNameTxt.setText(""); + primaryMailTxt.setText(""); + pwd1Txt.setText(""); + pwd2Txt.setText(""); + } else { + dNameTxt.setText(getDn(name)); + lastNameTxt.setText(name.toUpperCase()); + primaryMailTxt.setText(getMail(name)); + pwd1Txt.setText("demo"); + pwd2Txt.setText("demo"); + } + } + }); + + primaryMailTxt = EclipseUiUtils.createGridLT(composite, + "Email", this); + firstNameTxt = EclipseUiUtils.createGridLT(composite, + "First name", this); + lastNameTxt = EclipseUiUtils.createGridLT(composite, + "Last name", this); + pwd1Txt = EclipseUiUtils.createGridLP(composite, "Password", + this); + pwd2Txt = EclipseUiUtils.createGridLP(composite, + "Repeat password", this); + setControl(composite); + + // Initialize buttons + setPageComplete(false); + getContainer().updateButtons(); + } + + @Override + public void modifyText(ModifyEvent event) { + String message = checkComplete(); + if (message != null) { + setMessage(message, WizardPage.ERROR); + setPageComplete(false); + } else { + setMessage("Complete", WizardPage.INFORMATION); + setPageComplete(true); + } + getContainer().updateButtons(); + } + + /** @return error message or null if complete */ + protected String checkComplete() { + String name = usernameTxt.getText(); + + if (name.trim().equals("")) + return "User name must not be empty"; + Role role = userAdminWrapper.getUserAdmin() + .getRole(getDn(name)); + if (role != null) + return "User " + name + " already exists"; + if (!primaryMailTxt.getText().matches(EMAIL_PATTERN)) + return "Not a valid email address"; + if (lastNameTxt.getText().trim().equals("")) + return "Specify a last name"; + if (pwd1Txt.getText().trim().equals("")) + return "Specify a password"; + if (pwd2Txt.getText().trim().equals("")) + return "Repeat the password"; + if (!pwd2Txt.getText().equals(pwd1Txt.getText())) + return "Passwords are different"; + return null; + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) + if (baseDnCmb.getSelectionIndex() == -1) + baseDnCmb.setFocus(); + else + usernameTxt.setFocus(); + } + + public String getUsername() { + return usernameTxt.getText(); + } + + public char[] getPassword() { + return pwd1Txt.getTextChars(); + } + + } + + private Map getDns() { + return userAdminWrapper.getKnownBaseDns(true); + } + + private String getDn(String uid) { + Map dns = getDns(); + String bdn = baseDnCmb.getText(); + if (EclipseUiUtils.notEmpty(bdn)) { + Dictionary props = UserAdminConf.uriAsProperties(dns + .get(bdn)); + String dn = LdifName.uid.name() + "=" + uid + "," + + UserAdminConf.userBase.getValue(props) + "," + bdn; + return dn; + } + return null; + } + + private void initialiseDnCmb(Combo combo) { + Map dns = userAdminWrapper.getKnownBaseDns(true); + if (dns.isEmpty()) + throw new CmsException( + "No writable base dn found. Cannot create user"); + combo.setItems(dns.keySet().toArray(new String[0])); + if (dns.size() == 1) + combo.select(0); + } + + private String getMail(String username) { + if (baseDnCmb.getSelectionIndex() == -1) + return null; + String baseDn = baseDnCmb.getText(); + try { + LdapName name = new LdapName(baseDn); + List rdns = name.getRdns(); + return username + "@" + (String) rdns.get(1).getValue() + '.' + + (String) rdns.get(0).getValue(); + } catch (InvalidNameException e) { + throw new CmsException("Unable to generate mail for " + + username + " with base dn " + baseDn, e); + } + } + } + + private Combo createGridLC(Composite parent, String label) { + Label lbl = new Label(parent, SWT.LEAD); + lbl.setText(label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY); + combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return combo; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java new file mode 100644 index 000000000..5d87202a1 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +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.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Save the currently edited Argeo user. */ +public class SaveArgeoUser extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".saveArgeoUser"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + IWorkbenchPart iwp = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getActivePart(); + if (!(iwp instanceof IEditorPart)) + return null; + IEditorPart editor = (IEditorPart) iwp; + editor.doSave(null); + } catch (Exception e) { + MessageDialog.openError(Display.getDefault().getActiveShell(), + "Error", "Cannot save user: " + e.getMessage()); + } + return null; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java new file mode 100644 index 000000000..4aaee0df4 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserBatchUpdateWizard; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Launch a wizard to perform batch process on users */ +public class UserBatchUpdate extends AbstractHandler { + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper uaWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + UserBatchUpdateWizard wizard = new UserBatchUpdateWizard(uaWrapper); + wizard.setWindowTitle("User batch processing"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + dialog.open(); + return null; + } + + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.uaWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java new file mode 100644 index 000000000..bcee7f039 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.commands; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UiAdminUtils; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Manage the transaction that is bound to the current perspective */ +public class UserTransactionHandler extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".userTransactionHandler"; + + public final static String PARAM_COMMAND_ID = "param.commandId"; + + public final static String TRANSACTION_BEGIN = "transaction.begin"; + public final static String TRANSACTION_COMMIT = "transaction.commit"; + public final static String TRANSACTION_ROLLBACK = "transaction.rollback"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + String commandId = event.getParameter(PARAM_COMMAND_ID); + final UserTransaction userTransaction = userAdminWrapper + .getUserTransaction(); + try { + if (TRANSACTION_BEGIN.equals(commandId)) { + if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION) + throw new CmsException("A transaction already exists"); + else + userTransaction.begin(); + } else if (TRANSACTION_COMMIT.equals(commandId)) { + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + throw new CmsException("No transaction."); + else + userTransaction.commit(); + } else if (TRANSACTION_ROLLBACK.equals(commandId)) { + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + throw new CmsException("No transaction to rollback."); + else { + userTransaction.rollback(); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, null)); + } + } + + UiAdminUtils.notifyTransactionStateChange(userTransaction); + // Try to remove invalid thread access errors when managing users. + // HandlerUtil.getActivePart(event).getSite().getShell().getDisplay() + // .asyncExec(new Runnable() { + // @Override + // public void run() { + // UiAdminUtils + // .notifyTransactionStateChange(userTransaction); + // } + // }); + + } catch (CmsException e) { + throw e; + } catch (Exception e) { + throw new CmsException("Unable to call " + commandId + " on " + + userTransaction, e); + } + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java new file mode 100644 index 000000000..d0ed6b45f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** Editor input for an Argeo user. */ +public class ArgeoUserEditorInput implements IEditorInput { + private final String username; + + public ArgeoUserEditorInput(String username) { + this.username = username; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return username != null; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return username != null ? username : ""; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return username != null ? username : ""; + } + + public boolean equals(Object obj) { + if (!(obj instanceof ArgeoUserEditorInput)) + return false; + if (((ArgeoUserEditorInput) obj).getUsername() == null) + return false; + return ((ArgeoUserEditorInput) obj).getUsername().equals(username); + } + + public String getUsername() { + return username; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/DefaultUserMainPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/DefaultUserMainPage.java new file mode 100644 index 000000000..6d7f2bf3f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/DefaultUserMainPage.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.Arrays; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.node.ArgeoNames; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.SectionPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; + +/** Display/edit the properties common to all Argeo users */ +public class DefaultUserMainPage extends FormPage implements ArgeoNames { + final static String ID = "argeoUserEditor.mainPage"; + + private final static Log log = LogFactory.getLog(DefaultUserMainPage.class); + private Node userProfile; + + private char[] newPassword; + + public DefaultUserMainPage(FormEditor editor, Node userProfile) { + super(editor, ID, "Main"); + this.userProfile = userProfile; + } + + protected void createFormContent(final IManagedForm mf) { + try { + ScrolledForm form = mf.getForm(); + refreshFormTitle(form); + GridLayout mainLayout = new GridLayout(1, true); + form.getBody().setLayout(mainLayout); + + createGeneralPart(form.getBody()); + createPassworPart(form.getBody()); + } catch (RepositoryException e) { + throw new CmsException("Cannot create form content", e); + } + } + + /** Creates the general section */ + protected void createGeneralPart(Composite parent) + throws RepositoryException { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = tk.createSection(parent, Section.TITLE_BAR); + section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + section.setText("General"); + Composite body = tk.createComposite(section, SWT.WRAP); + section.setClient(body); + GridLayout layout = new GridLayout(2, false); + body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + body.setLayout(layout); + + final Text commonName = createLT(body, "Displayed Name", + getProperty(Property.JCR_TITLE)); + final Text firstName = createLT(body, "First name", + getProperty(ARGEO_FIRST_NAME)); + final Text lastName = createLT(body, "Last name", + getProperty(ARGEO_LAST_NAME)); + final Text email = createLT(body, "Email", + getProperty(ARGEO_PRIMARY_EMAIL)); + final Text description = createLMT(body, "Description", + getProperty(Property.JCR_DESCRIPTION)); + + // create form part (controller) + AbstractFormPart part = new SectionPart(section) { + public void commit(boolean onSave) { + try { + userProfile.getSession().getWorkspace().getVersionManager() + .checkout(userProfile.getPath()); + userProfile.setProperty(Property.JCR_TITLE, + commonName.getText()); + userProfile.setProperty(ARGEO_FIRST_NAME, + firstName.getText()); + userProfile + .setProperty(ARGEO_LAST_NAME, lastName.getText()); + userProfile.setProperty(ARGEO_PRIMARY_EMAIL, + email.getText()); + userProfile.setProperty(Property.JCR_DESCRIPTION, + description.getText()); + userProfile.getSession().save(); + userProfile.getSession().getWorkspace().getVersionManager() + .checkin(userProfile.getPath()); + super.commit(onSave); + refreshFormTitle(getManagedForm().getForm()); + if (log.isTraceEnabled()) + log.trace("General part committed"); + } catch (RepositoryException e) { + throw new CmsException("Cannot commit", e); + } + } + }; + // if (username != null) + // username.addModifyListener(new FormPartML(part)); + commonName.addModifyListener(new FormPartML(part)); + firstName.addModifyListener(new FormPartML(part)); + lastName.addModifyListener(new FormPartML(part)); + email.addModifyListener(new FormPartML(part)); + description.addModifyListener(new FormPartML(part)); + getManagedForm().addPart(part); + } + + private void refreshFormTitle(ScrolledForm form) throws RepositoryException { + form.setText(getProperty(Property.JCR_TITLE) + + (userProfile.getProperty(ARGEO_ENABLED).getBoolean() ? "" + : " [DISABLED]")); + } + + /** @return the property, or the empty string if not set */ + protected String getProperty(String name) throws RepositoryException { + return userProfile.hasProperty(name) ? userProfile.getProperty(name) + .getString() : ""; + } + + /** Creates the password section */ + protected void createPassworPart(Composite parent) { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = tk.createSection(parent, Section.TITLE_BAR); + section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + section.setText("Password"); + + Composite body = tk.createComposite(section, SWT.WRAP); + section.setClient(body); + GridLayout layout = new GridLayout(2, false); + body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + body.setLayout(layout); + + // add widgets (view) + final Text password1 = createLP(body, "New password", ""); + final Text password2 = createLP(body, "Repeat password", ""); + // create form part (controller) + AbstractFormPart part = new SectionPart(section) { + + public void commit(boolean onSave) { + if (!password1.getText().equals("") + || !password2.getText().equals("")) { + if (password1.getText().equals(password2.getText())) { + newPassword = password1.getText().toCharArray(); + password1.setText(""); + password2.setText(""); + super.commit(onSave); + } else { + password1.setText(""); + password2.setText(""); + throw new CmsException("Passwords are not equals"); + } + } + } + + }; + password1.addModifyListener(new FormPartML(part)); + password2.addModifyListener(new FormPartML(part)); + getManagedForm().addPart(part); + } + + /** Creates label and text. */ + protected Text createLT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + /** Creates label and multiline text. */ + protected Text createLMT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + return text; + } + + /** Creates label and password. */ + protected Text createLP(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + private class FormPartML implements ModifyListener { + private static final long serialVersionUID = 6299808129505381333L; + private AbstractFormPart formPart; + + public FormPartML(AbstractFormPart generalPart) { + this.formPart = generalPart; + } + + public void modifyText(ModifyEvent e) { + formPart.markDirty(); + } + } + + public String getNewPassword() { + if (newPassword != null) + return new String(newPassword); + else + return null; + } + + public void resetNewPassword() { + if (newPassword != null) + Arrays.fill(newPassword, 'x'); + newPassword = null; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java new file mode 100644 index 000000000..0c8e55593 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.GroupChangeListener; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.MainInfoListener; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.MailLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserFilter; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.SectionPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Display/edit main properties of a given group */ +public class GroupMainPage extends FormPage implements ArgeoNames { + final static String ID = "GroupEditor.mainPage"; + + private final UserEditor editor; + private UserAdminWrapper userAdminWrapper; + + // Local configuration + private final int PRE_TITLE_INDENT = 10; + + public GroupMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) { + super(editor, ID, "Main"); + this.editor = (UserEditor) editor; + this.userAdminWrapper = userAdminWrapper; + } + + protected void createFormContent(final IManagedForm mf) { + ScrolledForm form = mf.getForm(); + Composite body = form.getBody(); + GridLayout mainLayout = new GridLayout(); + body.setLayout(mainLayout); + Group group = (Group) editor.getDisplayedUser(); + appendOverviewPart(body, group); + appendMembersPart(body, group); + } + + /** Creates the general section */ + protected void appendOverviewPart(final Composite parent, final Group group) { + FormToolkit tk = getManagedForm().getToolkit(); + Composite body = addSection(tk, parent, "Main information"); + GridLayout layout = new GridLayout(2, false); + body.setLayout(layout); + + final Text dnTxt = createLT(body, "DN", group.getName()); + dnTxt.setEnabled(false); + + final Text cnTxt = createLT(body, "Common Name", + UserAdminUtils.getProperty(group, LdifName.cn.name())); + cnTxt.setEnabled(false); + + Label descLbl = new Label(body, SWT.LEAD); + descLbl.setText("Description"); + descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); + final Text descTxt = new Text(body, SWT.LEAD | SWT.MULTI | SWT.WRAP + | SWT.BORDER); + GridData gd = EclipseUiUtils.fillAll(); + gd.heightHint = 100; + descTxt.setLayoutData(gd); + + // create form part (controller) + AbstractFormPart part = new SectionPart((Section) body.getParent()) { + + private MainInfoListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.new MainInfoListener(parent.getDisplay(), + this); + userAdminWrapper.addListener(listener); + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @SuppressWarnings("unchecked") + public void commit(boolean onSave) { + group.getProperties().put(LdifName.description.name(), + descTxt.getText()); + // Enable common name ? + // editor.setProperty(UserAdminConstants.KEY_CN, + // email.getText()); + super.commit(onSave); + } + + @Override + public void refresh() { + refreshFormTitle(group); + dnTxt.setText(group.getName()); + cnTxt.setText(UserAdminUtils.getProperty(group, + LdifName.cn.name())); + descTxt.setText(UserAdminUtils.getProperty(group, + LdifName.description.name())); + super.refresh(); + } + }; + + ModifyListener defaultListener = editor.new FormPartML(part); + descTxt.addModifyListener(defaultListener); + getManagedForm().addPart(part); + } + + /** Filtered table with members. Has drag & drop ability */ + protected void appendMembersPart(Composite parent, Group group) { + + FormToolkit tk = getManagedForm().getToolkit(); + Section section = tk.createSection(parent, Section.TITLE_BAR); + section.setLayoutData(EclipseUiUtils.fillAll()); + + Composite body = new Composite(section, SWT.NO_FOCUS); + section.setClient(body); + body.setLayoutData(EclipseUiUtils.fillAll()); + + LdifUsersTable userTableViewerCmp = createMemberPart(body, group); + + SectionPart part = new GroupMembersPart(section, userTableViewerCmp, + group); + getManagedForm().addPart(part); + addRemoveAbitily(part, userTableViewerCmp.getTableViewer(), group); + } + + public LdifUsersTable createMemberPart(Composite parent, Group group) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // Define the displayed columns + List columnDefs = new ArrayList(); + columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + columnDefs.add(new ColumnDefinition(new MailLP(), "Primary Mail", 150)); + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 240)); + + // Create and configure the table + LdifUsersTable userViewerCmp = new MyUserTableViewer(parent, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL, userAdminWrapper.getUserAdmin()); + + userViewerCmp.setColumnDefinitions(columnDefs); + userViewerCmp.populate(true, false); + userViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); + + // Controllers + TableViewer userViewer = userViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + userViewer.addDropSupport(operations, tt, + new GroupDropListener(userAdminWrapper, userViewerCmp, + (Group) editor.getDisplayedUser())); + + return userViewerCmp; + } + + // Local viewers + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 8467999509931900367L; + + private final UserFilter userFilter; + + public MyUserTableViewer(Composite parent, int style, + UserAdmin userAdmin) { + super(parent, style, true); + userFilter = new UserFilter(); + + } + + @Override + protected List listFilteredElements(String filter) { + Group group = (Group) editor.getDisplayedUser(); + Role[] roles = group.getMembers(); + List users = new ArrayList(); + userFilter.setSearchText(filter); + for (Role role : roles) + // if (role.getType() == Role.GROUP) + if (userFilter.select(null, null, role)) + users.add((User) role); + return users; + } + } + + private void addRemoveAbitily(SectionPart sectionPart, + TableViewer userViewer, Group group) { + Section section = sectionPart.getSection(); + ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); + ToolBar toolbar = toolBarManager.createControl(section); + final Cursor handCursor = new Cursor(section.getDisplay(), + SWT.CURSOR_HAND); + toolbar.setCursor(handCursor); + toolbar.addDisposeListener(new DisposeListener() { + private static final long serialVersionUID = 3882131405820522925L; + + public void widgetDisposed(DisposeEvent e) { + if ((handCursor != null) && (handCursor.isDisposed() == false)) { + handCursor.dispose(); + } + } + }); + + Action action = new RemoveMembershipAction(userViewer, group, + "Remove selected items from this group", + SecurityAdminImages.ICON_REMOVE_DESC); + toolBarManager.add(action); + toolBarManager.update(true); + section.setTextClient(toolbar); + } + + private class RemoveMembershipAction extends Action { + private static final long serialVersionUID = -1337713097184522588L; + + private final TableViewer userViewer; + private final Group group; + + RemoveMembershipAction(TableViewer userViewer, Group group, + String name, ImageDescriptor img) { + super(name, img); + this.userViewer = userViewer; + this.group = group; + } + + @Override + public void run() { + ISelection selection = userViewer.getSelection(); + if (selection.isEmpty()) + return; + + @SuppressWarnings("unchecked") + Iterator it = ((IStructuredSelection) selection).iterator(); + List users = new ArrayList(); + while (it.hasNext()) { + User currUser = it.next(); + users.add(currUser); + } + + userAdminWrapper.beginTransactionIfNeeded(); + for (User user : users) { + group.removeMember(user); + } + userAdminWrapper.commitOrNotifyTransactionStateChange(); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, group)); + } + } + + // LOCAL CONTROLLERS + private class GroupMembersPart extends SectionPart { + private final LdifUsersTable userViewer; + private final Group group; + + private GroupChangeListener listener; + + public GroupMembersPart(Section section, LdifUsersTable userViewer, + Group group) { + super(section); + this.userViewer = userViewer; + this.group = group; + } + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.new GroupChangeListener(userViewer.getDisplay(), + GroupMembersPart.this); + userAdminWrapper.addListener(listener); + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void refresh() { + refreshFormTitle(group); + getSection().setText( + "Members of group " + + UserAdminUtils.getProperty(group, + LdifName.cn.name())); + userViewer.refresh(); + super.refresh(); + } + } + + /** + * Defines this table as being a potential target to add group membership + * (roles) to this group + */ + private class GroupDropListener extends ViewerDropAdapter { + private static final long serialVersionUID = 2893468717831451621L; + + private final UserAdminWrapper userAdminWrapper; + // private final LdifUsersTable myUserViewerCmp; + private final Group myGroup; + + public GroupDropListener(UserAdminWrapper userAdminWrapper, + LdifUsersTable userTableViewerCmp, Group group) { + super(userTableViewerCmp.getTableViewer()); + this.userAdminWrapper = userAdminWrapper; + this.myGroup = group; + // this.myUserViewerCmp = userTableViewerCmp; + } + + @Override + public boolean validateDrop(Object target, int operation, + TransferData transferType) { + // Target is always OK in a list only view + // TODO check if not a string + boolean validDrop = true; + return validDrop; + } + + @Override + public void drop(DropTargetEvent event) { + // TODO Is there an opportunity to perform the check before? + + String newUserName = (String) event.data; + UserAdmin myUserAdmin = userAdminWrapper.getUserAdmin(); + Role role = myUserAdmin.getRole(newUserName); + if (role.getType() == Role.GROUP) { + Group newGroup = (Group) role; + Shell shell = getViewer().getControl().getShell(); + // Sanity checks + if (myGroup == newGroup) { // Equality + MessageDialog.openError(shell, "Forbidden addition ", + "A group cannot be a member of itself."); + return; + } + + // Cycle + String myName = myGroup.getName(); + List myMemberships = editor.getFlatGroups(myGroup); + if (myMemberships.contains(newGroup)) { + MessageDialog.openError(shell, "Forbidden addition: cycle", + "Cannot add " + newUserName + " to group " + myName + + ". This would create a cycle"); + return; + } + + // Already member + List newGroupMemberships = editor.getFlatGroups(newGroup); + if (newGroupMemberships.contains(myGroup)) { + MessageDialog.openError(shell, "Forbidden addition", + "Cannot add " + newUserName + " to group " + myName + + ", this membership already exists"); + return; + } + userAdminWrapper.beginTransactionIfNeeded(); + myGroup.addMember(newGroup); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, myGroup)); + } else if (role.getType() == Role.USER) { + // TODO check if the group is already member of this group + UserTransaction transaction = userAdminWrapper + .beginTransactionIfNeeded(); + User user = (User) role; + myGroup.addMember(user); + if (UserAdminWrapper.COMMIT_ON_SAVE) + try { + transaction.commit(); + } catch (Exception e) { + throw new CmsException("Cannot commit transaction " + + "after user group membership update", e); + } + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, myGroup)); + } + super.drop(event); + } + + @Override + public boolean performDrop(Object data) { + // myUserViewerCmp.refresh(); + return true; + } + } + + // LOCAL HELPERS + private void refreshFormTitle(Group group) { + getManagedForm().getForm().setText( + UserAdminUtils.getProperty(group, LdifName.cn.name())); + } + + private Composite addSection(FormToolkit tk, Composite parent, String title) { + Section section = tk.createSection(parent, Section.TITLE_BAR); + GridData gd = EclipseUiUtils.fillWidth(); + gd.verticalAlignment = PRE_TITLE_INDENT; + section.setLayoutData(gd); + section.setText(title); + Composite body = tk.createComposite(section, SWT.WRAP); + body.setLayoutData(EclipseUiUtils.fillAll()); + section.setClient(body); + return body; + } + + /** Creates label and text. */ + private Text createLT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java new file mode 100644 index 000000000..32bbc9ffb --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.DomainNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserDragListener; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdminEvent; +import org.osgi.service.useradmin.UserAdminListener; + +/** List all groups with filter */ +public class GroupsView extends ViewPart implements ArgeoNames { + private final static Log log = LogFactory.getLog(GroupsView.class); + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupsView"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + // UI Objects + private LdifUsersTable groupTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + private UserAdminListener listener; + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + boolean isAdmin = UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN); + + // Define the displayed columns + columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 26)); + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); + // Only show technical DN to admin + if (isAdmin) + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 300)); + + // Create and configure the table + groupTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + + groupTableViewerCmp.setColumnDefinitions(columnDefs); + if (isAdmin) + groupTableViewerCmp.populateWithStaticFilters(false, false); + else + groupTableViewerCmp.populate(true, false); + + groupTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); + + // Links + userViewer = groupTableViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); + getViewSite().setSelectionProvider(userViewer); + + // Really? + groupTableViewerCmp.refresh(); + + // Drag and drop + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + userViewer.addDragSupport(operations, tt, new UserDragListener( + userViewer)); + + // // Register a useradmin listener + // listener = new UserAdminListener() { + // @Override + // public void roleChanged(UserAdminEvent event) { + // if (userViewer != null && !userViewer.getTable().isDisposed()) + // refresh(); + // } + // }; + // userAdminWrapper.addListener(listener); + // } + + // Register a useradmin listener + listener = new MyUiUAListener(parent.getDisplay()); + userAdminWrapper.addListener(listener); + } + + private class MyUiUAListener extends UiUserAdminListener { + public MyUiUAListener(Display display) { + super(display); + } + + @Override + public void roleChangedToUiThread(UserAdminEvent event) { + if (userViewer != null && !userViewer.getTable().isDisposed()) + refresh(); + } + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 8467999509931900367L; + + private boolean showSystemRoles = false; + + private final String[] knownProps = { LdifName.uid.name(), + LdifName.cn.name(), LdifName.dn.name() }; + + public MyUserTableViewer(Composite parent, int style) { + super(parent, style); + } + + protected void populateStaticFilters(Composite staticFilterCmp) { + staticFilterCmp.setLayout(new GridLayout()); + final Button showSystemRoleBtn = new Button(staticFilterCmp, + SWT.CHECK); + showSystemRoleBtn.setText("Show system roles"); + showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + showSystemRoles = showSystemRoleBtn.getSelection(); + refresh(); + } + + }); + } + + @Override + protected List listFilteredElements(String filter) { + Role[] roles; + try { + StringBuilder builder = new StringBuilder(); + StringBuilder tmpBuilder = new StringBuilder(); + if (EclipseUiUtils.notEmpty(filter)) + for (String prop : knownProps) { + tmpBuilder.append("("); + tmpBuilder.append(prop); + tmpBuilder.append("=*"); + tmpBuilder.append(filter); + tmpBuilder.append("*)"); + } + if (tmpBuilder.length() > 1) { + builder.append("(&(").append(LdifName.objectClass.name()) + .append("=").append(LdifName.groupOfNames.name()) + .append(")"); + if (!showSystemRoles) + builder.append("(!(").append(LdifName.dn.name()) + .append("=*") + .append(AuthConstants.ROLES_BASEDN) + .append("))"); + builder.append("(|"); + builder.append(tmpBuilder.toString()); + builder.append("))"); + } else { + if (!showSystemRoles) + builder.append("(&(") + .append(LdifName.objectClass.name()) + .append("=") + .append(LdifName.groupOfNames.name()) + .append(")(!(").append(LdifName.dn.name()) + .append("=*") + .append(AuthConstants.ROLES_BASEDN) + .append(")))"); + else + builder.append("(").append(LdifName.objectClass.name()) + .append("=") + .append(LdifName.groupOfNames.name()) + .append(")"); + + } + roles = userAdminWrapper.getUserAdmin().getRoles( + builder.toString()); + } catch (InvalidSyntaxException e) { + throw new CmsException("Unable to get roles with filter: " + + filter, e); + } + List users = new ArrayList(); + for (Role role : roles) + if (!users.contains(role)) + users.add((User) role); + else + log.warn("Duplicated role: " + role); + + return users; + } + } + + public void refresh() { + groupTableViewerCmp.refresh(); + } + + // Override generic view methods + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void setFocus() { + groupTableViewerCmp.setFocus(); + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java new file mode 100644 index 000000000..984008bf7 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java @@ -0,0 +1,578 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.transaction.SystemException; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.DomainNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.MailLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.dialogs.IPageChangeProvider; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** Wizard to update users */ +public class UserBatchUpdateWizard extends Wizard { + + private final static Log log = LogFactory + .getLog(UserBatchUpdateWizard.class); + private UserAdminWrapper userAdminWrapper; + + // pages + private ChooseCommandWizardPage chooseCommandPage; + private ChooseUsersWizardPage userListPage; + private ValidateAndLaunchWizardPage validatePage; + + // Various implemented commands keys + private final static String CMD_UPDATE_PASSWORD = "resetPassword"; + private final static String CMD_GROUP_MEMBERSHIP = "groupMembership"; + + private final Map commands = new HashMap() { + private static final long serialVersionUID = 1L; + { + put("Reset password(s)", CMD_UPDATE_PASSWORD); + // TODO implement role / group management + // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP); + } + }; + + public UserBatchUpdateWizard(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } + + @Override + public void addPages() { + chooseCommandPage = new ChooseCommandWizardPage(); + addPage(chooseCommandPage); + userListPage = new ChooseUsersWizardPage(); + addPage(userListPage); + validatePage = new ValidateAndLaunchWizardPage(); + addPage(validatePage); + } + + @Override + public boolean performFinish() { + if (!canFinish()) + return false; + UserTransaction ut = userAdminWrapper.getUserTransaction(); + try { + if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION + && !MessageDialog.openConfirm(getShell(), + "Existing Transaction", + "A user transaction is already existing, " + + "are you sure you want to proceed ?")) + return false; + } catch (SystemException e) { + throw new CmsException("Cannot get user transaction state " + + "before user batch update", e); + } + + // We cannot use jobs, user modifications are still meant to be done in + // the UIThread + // UpdateJob job = null; + // if (job != null) + // job.schedule(); + + if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) { + char[] newValue = chooseCommandPage.getPwdValue(); + if (newValue == null) + throw new CmsException( + "Password cannot be null or an empty string"); + ResetPassword job = new ResetPassword(userAdminWrapper, + userListPage.getSelectedUsers(), newValue); + job.doUpdate(); + } + return true; + } + + public boolean canFinish() { + if (this.getContainer().getCurrentPage() == validatePage) + return true; + return false; + } + + private class ResetPassword { + private char[] newPwd; + private UserAdminWrapper userAdminWrapper; + private List usersToUpdate; + + public ResetPassword(UserAdminWrapper userAdminWrapper, + List usersToUpdate, char[] newPwd) { + this.newPwd = newPwd; + this.usersToUpdate = usersToUpdate; + this.userAdminWrapper = userAdminWrapper; + } + + @SuppressWarnings("unchecked") + protected void doUpdate() { + userAdminWrapper.beginTransactionIfNeeded(); + try { + for (User user : usersToUpdate) { + // the char array is emptied after being used. + user.getCredentials().put(null, newPwd.clone()); + } + userAdminWrapper.commitOrNotifyTransactionStateChange(); + } catch (Exception e) { + throw new CmsException("Cannot perform batch update on users", + e); + } finally { + UserTransaction ut = userAdminWrapper.getUserTransaction(); + try { + if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION) + ut.rollback(); + } catch (IllegalStateException | SecurityException + | SystemException e) { + log.error("Unable to rollback session in 'finally', " + + "the system might be in a dirty state"); + e.printStackTrace(); + } + } + } + } + + // @SuppressWarnings("unused") + // private class AddToGroup extends UpdateJob { + // private String groupID; + // private Session session; + // + // public AddToGroup(Session session, List nodesToUpdate, + // String groupID) { + // super(session, nodesToUpdate); + // this.session = session; + // this.groupID = groupID; + // } + // + // protected void doUpdate(Node node) { + // log.info("Add/Remove to group actions are not yet implemented"); + // // TODO implement this + // // try { + // // throw new CmsException("Not yet implemented"); + // // } catch (RepositoryException re) { + // // throw new CmsException( + // // "Unable to update boolean value for node " + node, re); + // // } + // } + // } + + // /** + // * Base privileged job that will be run asynchronously to perform the + // batch + // * update + // */ + // private abstract class UpdateJob extends PrivilegedJob { + // + // private final UserAdminWrapper userAdminWrapper; + // private final List usersToUpdate; + // + // protected abstract void doUpdate(User user); + // + // public UpdateJob(UserAdminWrapper userAdminWrapper, + // List usersToUpdate) { + // super("Perform update"); + // this.usersToUpdate = usersToUpdate; + // this.userAdminWrapper = userAdminWrapper; + // } + // + // @Override + // protected IStatus doRun(IProgressMonitor progressMonitor) { + // try { + // JcrMonitor monitor = new EclipseJcrMonitor(progressMonitor); + // int total = usersToUpdate.size(); + // monitor.beginTask("Performing change", total); + // userAdminWrapper.beginTransactionIfNeeded(); + // for (User user : usersToUpdate) { + // doUpdate(user); + // monitor.worked(1); + // } + // userAdminWrapper.getUserTransaction().commit(); + // } catch (Exception e) { + // throw new CmsException( + // "Cannot perform batch update on users", e); + // } finally { + // UserTransaction ut = userAdminWrapper.getUserTransaction(); + // try { + // if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION) + // ut.rollback(); + // } catch (IllegalStateException | SecurityException + // | SystemException e) { + // log.error("Unable to rollback session in 'finally', " + // + "the system might be in a dirty state"); + // e.printStackTrace(); + // } + // } + // return Status.OK_STATUS; + // } + // } + + // PAGES + /** Displays a combo box that enables user to choose which action to perform */ + private class ChooseCommandWizardPage extends WizardPage { + private static final long serialVersionUID = -8069434295293996633L; + private Combo chooseCommandCmb; + private Button trueChk; + private Text valueTxt; + private Text pwdTxt; + private Text pwd2Txt; + + public ChooseCommandWizardPage() { + super("Choose a command to run."); + setTitle("Choose a command to run."); + } + + @Override + public void createControl(Composite parent) { + GridLayout gl = new GridLayout(); + Composite container = new Composite(parent, SWT.NO_FOCUS); + container.setLayout(gl); + + chooseCommandCmb = new Combo(container, SWT.READ_ONLY); + chooseCommandCmb.setLayoutData(EclipseUiUtils.fillWidth()); + String[] values = commands.keySet().toArray(new String[0]); + chooseCommandCmb.setItems(values); + + final Composite bottomPart = new Composite(container, SWT.NO_FOCUS); + bottomPart.setLayoutData(EclipseUiUtils.fillAll()); + bottomPart.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + chooseCommandCmb.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + if (getCommand().equals(CMD_UPDATE_PASSWORD)) + populatePasswordCmp(bottomPart); + else if (getCommand().equals(CMD_GROUP_MEMBERSHIP)) + populateGroupCmp(bottomPart); + else + populateBooleanFlagCmp(bottomPart); + checkPageComplete(); + bottomPart.layout(true, true); + } + }); + setControl(container); + } + + private void populateBooleanFlagCmp(Composite parent) { + EclipseUiUtils.clear(parent); + trueChk = new Button(parent, SWT.CHECK); + trueChk.setText("Do it. (It will to the contrary if unchecked)"); + trueChk.setSelection(true); + trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); + } + + private void populatePasswordCmp(Composite parent) { + EclipseUiUtils.clear(parent); + Composite body = new Composite(parent, SWT.NO_FOCUS); + + ModifyListener ml = new ModifyListener() { + private static final long serialVersionUID = -1558726363536729634L; + + @Override + public void modifyText(ModifyEvent event) { + checkPageComplete(); + } + }; + + body.setLayout(new GridLayout(2, false)); + body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + pwdTxt = EclipseUiUtils.createGridLP(body, "New password", ml); + pwd2Txt = EclipseUiUtils.createGridLP(body, "Repeat password", ml); + } + + private void checkPageComplete() { + String errorMsg = null; + if (chooseCommandCmb.getSelectionIndex() < 0) + errorMsg = "Please select an action"; + else if (CMD_UPDATE_PASSWORD.equals(getCommand())) { + if (EclipseUiUtils.isEmpty(pwdTxt.getText()) + || pwdTxt.getText().length() < 4) + errorMsg = "Please enter a password that is at least 4 character long"; + else if (!pwdTxt.getText().equals(pwd2Txt.getText())) + errorMsg = "Passwords are different"; + } + if (EclipseUiUtils.notEmpty(errorMsg)) { + setMessage(errorMsg, WizardPage.ERROR); + setPageComplete(false); + } else { + setMessage("Page complete, you can proceed to user choice", + WizardPage.INFORMATION); + setPageComplete(true); + } + + getContainer().updateButtons(); + } + + private void populateGroupCmp(Composite parent) { + EclipseUiUtils.clear(parent); + trueChk = new Button(parent, SWT.CHECK); + trueChk.setText("Add to group. (It will remove user(s) from the " + + "corresponding group if unchecked)"); + trueChk.setSelection(true); + trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); + } + + protected String getCommand() { + return commands.get(chooseCommandCmb.getItem(chooseCommandCmb + .getSelectionIndex())); + } + + protected String getCommandLbl() { + return chooseCommandCmb.getItem(chooseCommandCmb + .getSelectionIndex()); + } + + @SuppressWarnings("unused") + protected boolean getBoleanValue() { + // FIXME this is not consistent and will lead to errors. + if (ArgeoNames.ARGEO_ENABLED.equals(getCommand())) + return trueChk.getSelection(); + else + return !trueChk.getSelection(); + } + + @SuppressWarnings("unused") + protected String getStringValue() { + String value = null; + if (valueTxt != null) { + value = valueTxt.getText(); + if ("".equals(value.trim())) + value = null; + } + return value; + } + + protected char[] getPwdValue() { + // We do not directly reset the password text fields: There is no + // need to over secure this process: setting a pwd to multi users + // at the same time is anyhow a bad practice and should be used only + // in test environment or for temporary access + if (pwdTxt == null || pwdTxt.isDisposed()) + return null; + else + return pwdTxt.getText().toCharArray(); + } + } + + /** + * Displays a list of users with a check box to be able to choose some of + * them + */ + private class ChooseUsersWizardPage extends WizardPage implements + IPageChangedListener { + private static final long serialVersionUID = 7651807402211214274L; + private ChooseUserTableViewer userTableCmp; + + public ChooseUsersWizardPage() { + super("Choose Users"); + setTitle("Select users who will be impacted"); + } + + @Override + public void createControl(Composite parent) { + Composite pageCmp = new Composite(parent, SWT.NONE); + pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // Define the displayed columns + List columnDefs = new ArrayList(); + columnDefs.add(new ColumnDefinition(new CommonNameLP(), + "Common Name", 150)); + columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); + columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", + 200)); + + // Only show technical DN to admin + if (UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN)) + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 300)); + + userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); + userTableCmp.setColumnDefinitions(columnDefs); + userTableCmp.populate(true, true); + userTableCmp.refresh(); + + setControl(pageCmp); + + // Add listener to update message when shown + final IWizardContainer wContainer = this.getContainer(); + if (wContainer instanceof IPageChangeProvider) { + ((IPageChangeProvider) wContainer).addPageChangedListener(this); + } + + } + + @Override + public void pageChanged(PageChangedEvent event) { + if (event.getSelectedPage() == this) { + String msg = "Chosen batch action: " + + chooseCommandPage.getCommandLbl(); + ((WizardPage) event.getSelectedPage()).setMessage(msg); + } + } + + protected List getSelectedUsers() { + return userTableCmp.getSelectedUsers(); + } + + private class ChooseUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 5080437561015853124L; + private final String[] knownProps = { LdifName.uid.name(), + LdifName.dn.name(), LdifName.cn.name(), + LdifName.givenName.name(), LdifName.sn.name(), + LdifName.mail.name() }; + + public ChooseUserTableViewer(Composite parent, int style) { + super(parent, style); + } + + @Override + protected List listFilteredElements(String filter) { + Role[] roles; + + try { + StringBuilder builder = new StringBuilder(); + + StringBuilder tmpBuilder = new StringBuilder(); + if (EclipseUiUtils.notEmpty(filter)) + for (String prop : knownProps) { + tmpBuilder.append("("); + tmpBuilder.append(prop); + tmpBuilder.append("=*"); + tmpBuilder.append(filter); + tmpBuilder.append("*)"); + } + if (tmpBuilder.length() > 1) { + builder.append("(&(") + .append(LdifName.objectClass.name()) + .append("=") + .append(LdifName.inetOrgPerson.name()) + .append(")(|"); + builder.append(tmpBuilder.toString()); + builder.append("))"); + } else + builder.append("(").append(LdifName.objectClass.name()) + .append("=") + .append(LdifName.inetOrgPerson.name()) + .append(")"); + roles = userAdminWrapper.getUserAdmin().getRoles( + builder.toString()); + } catch (InvalidSyntaxException e) { + throw new CmsException("Unable to get roles with filter: " + + filter, e); + } + List users = new ArrayList(); + for (Role role : roles) + // Prevent current logged in user to perform batch on + // himself + if (!UserAdminUtils.isCurrentUser((User) role)) + users.add((User) role); + return users; + } + } + } + + /** Summary of input data before launching the process */ + private class ValidateAndLaunchWizardPage extends WizardPage implements + IPageChangedListener { + private static final long serialVersionUID = 7098918351451743853L; + private ChosenUsersTableViewer userTableCmp; + + public ValidateAndLaunchWizardPage() { + super("Validate and launch"); + setTitle("Validate and launch"); + } + + @Override + public void createControl(Composite parent) { + Composite pageCmp = new Composite(parent, SWT.NO_FOCUS); + pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + List columnDefs = new ArrayList(); + columnDefs.add(new ColumnDefinition(new CommonNameLP(), + "Common Name", 150)); + columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); + columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", + 200)); + // Only show technical DN to admin + if (UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN)) + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 300)); + userTableCmp = new ChosenUsersTableViewer(pageCmp, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); + userTableCmp.setColumnDefinitions(columnDefs); + userTableCmp.populate(false, false); + userTableCmp.refresh(); + setControl(pageCmp); + // Add listener to update message when shown + final IWizardContainer wContainer = this.getContainer(); + if (wContainer instanceof IPageChangeProvider) { + ((IPageChangeProvider) wContainer).addPageChangedListener(this); + } + } + + @Override + public void pageChanged(PageChangedEvent event) { + if (event.getSelectedPage() == this) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + Object[] values = ((ArrayList) userListPage.getSelectedUsers()) + .toArray(new Object[userListPage.getSelectedUsers() + .size()]); + userTableCmp.getTableViewer().setInput(values); + String msg = "Following batch action: [" + + chooseCommandPage.getCommandLbl() + + "] will be perfomed on the users listed below.\n"; + // + "Are you sure you want to proceed?"; + setMessage(msg); + } + } + + private class ChosenUsersTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 7814764735794270541L; + + public ChosenUsersTableViewer(Composite parent, int style) { + super(parent, style); + } + + @Override + protected List listFilteredElements(String filter) { + return userListPage.getSelectedUsers(); + } + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java new file mode 100644 index 000000000..85ed08160 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.osgi.service.useradmin.Authorization; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Editor for a user, might be a user or a group. */ +public class UserEditor extends FormEditor { + private static final long serialVersionUID = 8357851520380820241L; + + public final static String USER_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID + + ".userEditor"; + public final static String GROUP_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID + + ".groupEditor"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + private UserAdmin userAdmin; + + // Context + private User user; + private String username; + + private NameChangeListener listener; + + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + super.init(site, input); + username = ((UserEditorInput) getEditorInput()).getUsername(); + user = (User) userAdmin.getRole(username); + + listener = new NameChangeListener(site.getShell().getDisplay(), user); + userAdminWrapper.addListener(listener); + updateEditorTitle(null); + } + + /** + * returns the list of all authorization for the given user or of the + * current displayed user if parameter is null + */ + protected List getFlatGroups(User aUser) { + Authorization currAuth; + if (aUser == null) + currAuth = userAdmin.getAuthorization(this.user); + else + currAuth = userAdmin.getAuthorization(aUser); + + String[] roles = currAuth.getRoles(); + + List groups = new ArrayList(); + for (String roleStr : roles) { + User currRole = (User) userAdmin.getRole(roleStr); + if (!groups.contains(currRole)) + groups.add(currRole); + } + return groups; + } + + /** Exposes the user (or group) that is displayed by the current editor */ + protected User getDisplayedUser() { + return user; + } + + void updateEditorTitle(String title) { + if (title == null) { + String commonName = UserAdminUtils.getProperty(user, + LdifName.cn.name()); + title = "".equals(commonName) ? user.getName() : commonName; + } + setPartName(title); + } + + protected void addPages() { + try { + if (user.getType() == Role.GROUP) + addPage(new GroupMainPage(this, userAdminWrapper)); + else + addPage(new UserMainPage(this, userAdminWrapper)); + } catch (Exception e) { + throw new CmsException("Cannot add pages", e); + } + } + + @Override + public void doSave(IProgressMonitor monitor) { + userAdminWrapper.beginTransactionIfNeeded(); + commitPages(true); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + firePropertyChange(PROP_DIRTY); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_REMOVED, user)); + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + // CONTROLERS FOR THIS EDITOR AND ITS PAGES + + private class NameChangeListener extends UiUserAdminListener { + + private final User user; + + public NameChangeListener(Display display, User user) { + super(display); + this.user = user; + } + + @Override + public void roleChangedToUiThread(UserAdminEvent event) { + Role changedRole = event.getRole(); + if (changedRole == null || changedRole.equals(user)) + updateEditorTitle(null); + } + } + + class MainInfoListener extends UiUserAdminListener { + private final AbstractFormPart part; + + public MainInfoListener(Display display, AbstractFormPart part) { + super(display); + this.part = part; + } + + @Override + public void roleChangedToUiThread(UserAdminEvent event) { + // Rollback + if (event.getRole() == null) + part.markStale(); + } + } + + class GroupChangeListener extends UiUserAdminListener { + private final AbstractFormPart part; + + public GroupChangeListener(Display display, AbstractFormPart part) { + super(display); + this.part = part; + } + + @Override + public void roleChangedToUiThread(UserAdminEvent event) { + // always mark as stale + part.markStale(); + } + } + + /** Registers a listener that will notify this part */ + class FormPartML implements ModifyListener { + private static final long serialVersionUID = 6299808129505381333L; + private AbstractFormPart formPart; + + public FormPartML(AbstractFormPart generalPart) { + this.formPart = generalPart; + } + + public void modifyText(ModifyEvent e) { + // Discard event when the control does not have the focus, typically + // to avoid all editors being marked as dirty during a Rollback + if (((Control) e.widget).isFocusControl()) + formPart.markDirty(); + } + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + this.userAdmin = userAdminWrapper.getUserAdmin(); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java new file mode 100644 index 000000000..576c53e6d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * Editor input for an user defined by unique name (usually a distinguished + * name). + */ +public class UserEditorInput implements IEditorInput { + private final String username; + + public UserEditorInput(String username) { + this.username = username; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return username != null; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return username != null ? username : ""; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return username != null ? username : ""; + } + + public boolean equals(Object obj) { + if (!(obj instanceof UserEditorInput)) + return false; + if (((UserEditorInput) obj).getUsername() == null) + return false; + return ((UserEditorInput) obj).getUsername().equals(username); + } + + public String getUsername() { + return username; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java new file mode 100644 index 000000000..ea0b8784a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java @@ -0,0 +1,539 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.GroupChangeListener; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.MainInfoListener; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.DomainNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserFilter; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +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.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.SectionPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Display/edit the properties of a given user */ +public class UserMainPage extends FormPage implements ArgeoNames { + final static String ID = "UserEditor.mainPage"; + + private final UserEditor editor; + private UserAdminWrapper userAdminWrapper; + + // Local configuration + private final int PRE_TITLE_INDENT = 10; + + public UserMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) { + super(editor, ID, "Main"); + this.editor = (UserEditor) editor; + this.userAdminWrapper = userAdminWrapper; + } + + protected void createFormContent(final IManagedForm mf) { + ScrolledForm form = mf.getForm(); + Composite body = form.getBody(); + GridLayout mainLayout = new GridLayout(); + // mainLayout.marginRight = 10; + body.setLayout(mainLayout); + User user = editor.getDisplayedUser(); + appendOverviewPart(body, user); + // Remove to ability to force the password for his own user. The user + // must then use the change pwd feature + if (!UserAdminUtils.isCurrentUser(user)) + appendPasswordPart(body, user); + appendMemberOfPart(body, user); + } + + /** Creates the general section */ + private void appendOverviewPart(final Composite parent, final User user) { + FormToolkit tk = getManagedForm().getToolkit(); + + Section section = addSection(tk, parent, "Main information"); + Composite body = (Composite) section.getClient(); + body.setLayout(new GridLayout(2, false)); + + final Text distinguishedName = createLT(tk, body, "User Name", + UserAdminUtils.getProperty(user, LdifName.uid.name())); + distinguishedName.setEnabled(false); + + final Text commonName = createLT(tk, body, "Common Name", + UserAdminUtils.getProperty(user, LdifName.cn.name())); + commonName.setEnabled(false); + + final Text firstName = createLT(tk, body, "First name", + UserAdminUtils.getProperty(user, LdifName.givenName.name())); + + final Text lastName = createLT(tk, body, "Last name", + UserAdminUtils.getProperty(user, LdifName.sn.name())); + + final Text email = createLT(tk, body, "Email", + UserAdminUtils.getProperty(user, LdifName.mail.name())); + + // create form part (controller) + AbstractFormPart part = new SectionPart((Section) body.getParent()) { + private MainInfoListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.new MainInfoListener(parent.getDisplay(), + this); + userAdminWrapper.addListener(listener); + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @SuppressWarnings("unchecked") + public void commit(boolean onSave) { + // TODO Sanity checks (mail validity...) + user.getProperties().put(LdifName.givenName.name(), + firstName.getText()); + user.getProperties() + .put(LdifName.sn.name(), lastName.getText()); + user.getProperties().put(LdifName.cn.name(), + commonName.getText()); + user.getProperties().put(LdifName.mail.name(), email.getText()); + super.commit(onSave); + } + + @Override + public void refresh() { + distinguishedName.setText(UserAdminUtils.getProperty(user, + LdifName.uid.name())); + commonName.setText(UserAdminUtils.getProperty(user, + LdifName.cn.name())); + firstName.setText(UserAdminUtils.getProperty(user, + LdifName.givenName.name())); + lastName.setText(UserAdminUtils.getProperty(user, + LdifName.sn.name())); + email.setText(UserAdminUtils.getProperty(user, + LdifName.mail.name())); + refreshFormTitle(user); + super.refresh(); + } + }; + + // Improve this: automatically generate CN when first or last name + // changes + ModifyListener cnML = new ModifyListener() { + private static final long serialVersionUID = 4298649222869835486L; + + @Override + public void modifyText(ModifyEvent event) { + String first = firstName.getText(); + String last = lastName.getText(); + String cn = first.trim() + " " + last.trim() + " "; + cn = cn.trim(); + commonName.setText(cn); + getManagedForm().getForm().setText(cn); + editor.updateEditorTitle(cn); + } + }; + firstName.addModifyListener(cnML); + lastName.addModifyListener(cnML); + + ModifyListener defaultListener = editor.new FormPartML(part); + firstName.addModifyListener(defaultListener); + lastName.addModifyListener(defaultListener); + email.addModifyListener(defaultListener); + getManagedForm().addPart(part); + } + + /** Creates the password section */ + private void appendPasswordPart(Composite parent, final User user) { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = addSection(tk, parent, "Password"); + Composite body = (Composite) section.getClient(); + body.setLayout(new GridLayout(2, false)); + + // add widgets (view) + final Text password1 = createLP(tk, body, "New password", ""); + final Text password2 = createLP(tk, body, "Repeat password", ""); + + // create form part (controller) + AbstractFormPart part = new SectionPart((Section) body.getParent()) { + @SuppressWarnings("unchecked") + public void commit(boolean onSave) { + if (!password1.getText().equals("") + || !password2.getText().equals("")) { + if (password1.getText().equals(password2.getText())) { + char[] newPassword = password1.getText().toCharArray(); + // userAdminWrapper.beginTransactionIfNeeded(); + user.getCredentials().put(null, newPassword); + password1.setText(""); + password2.setText(""); + super.commit(onSave); + } else { + password1.setText(""); + password2.setText(""); + throw new CmsException("Passwords are not equals"); + } + } + } + }; + ModifyListener defaultListener = editor.new FormPartML(part); + password1.addModifyListener(defaultListener); + password2.addModifyListener(defaultListener); + getManagedForm().addPart(part); + } + + private LdifUsersTable appendMemberOfPart(final Composite parent, User user) { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = addSection(tk, parent, "Roles"); + Composite body = (Composite) section.getClient(); + body.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + boolean isAdmin = UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN); + + // Displayed columns + List columnDefs = new ArrayList(); + columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain Name", + 200)); + // Only show technical DN to administrators + if (isAdmin) + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 120)); + + // Create and configure the table + final LdifUsersTable userViewerCmp = new MyUserTableViewer(body, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, user); + + userViewerCmp.setColumnDefinitions(columnDefs); + if (isAdmin) + userViewerCmp.populateWithStaticFilters(false, false); + else + userViewerCmp.populate(true, false); + GridData gd = EclipseUiUtils.fillAll(); + gd.heightHint = 300; + userViewerCmp.setLayoutData(gd); + + // Controllers + TableViewer userViewer = userViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + GroupDropListener dropL = new GroupDropListener(userAdminWrapper, + userViewer, user); + userViewer.addDropSupport(operations, tt, dropL); + + SectionPart part = new SectionPart((Section) body.getParent()) { + + private GroupChangeListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.new GroupChangeListener(parent.getDisplay(), + this); + userAdminWrapper.addListener(listener); + } + + public void commit(boolean onSave) { + super.commit(onSave); + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void refresh() { + userViewerCmp.refresh(); + super.refresh(); + } + }; + getManagedForm().addPart(part); + addRemoveAbitily(part, userViewer, user); + return userViewerCmp; + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 2653790051461237329L; + + private Button showSystemRoleBtn; + + private final User user; + private final UserFilter userFilter; + + public MyUserTableViewer(Composite parent, int style, User user) { + super(parent, style, true); + this.user = user; + userFilter = new UserFilter(); + userFilter.setShowSystemRole(false); + } + + protected void populateStaticFilters(Composite staticFilterCmp) { + staticFilterCmp.setLayout(new GridLayout()); + showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); + showSystemRoleBtn.setText("Show system roles"); + showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + userFilter.setShowSystemRole(showSystemRoleBtn + .getSelection()); + refresh(); + } + }); + } + + @Override + protected List listFilteredElements(String filter) { + List users = (List) editor.getFlatGroups(null); + List filteredUsers = new ArrayList(); + if (users.contains(user)) + users.remove(user); + userFilter.setSearchText(filter); + for (User user : users) + if (userFilter.select(null, null, user)) + filteredUsers.add(user); + return filteredUsers; + } + } + + private void addRemoveAbitily(SectionPart sectionPart, + TableViewer userViewer, User user) { + Section section = sectionPart.getSection(); + ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); + ToolBar toolbar = toolBarManager.createControl(section); + final Cursor handCursor = new Cursor(section.getDisplay(), + SWT.CURSOR_HAND); + toolbar.setCursor(handCursor); + toolbar.addDisposeListener(new DisposeListener() { + private static final long serialVersionUID = 3882131405820522925L; + + public void widgetDisposed(DisposeEvent e) { + if ((handCursor != null) && (handCursor.isDisposed() == false)) { + handCursor.dispose(); + } + } + }); + + String tooltip = "Remove " + UserAdminUtils.getUsername(user) + + " from the below selected groups"; + Action action = new RemoveMembershipAction(userViewer, user, tooltip, + SecurityAdminImages.ICON_REMOVE_DESC); + toolBarManager.add(action); + toolBarManager.update(true); + section.setTextClient(toolbar); + } + + private class RemoveMembershipAction extends Action { + private static final long serialVersionUID = -1337713097184522588L; + + private final TableViewer userViewer; + private final User user; + + RemoveMembershipAction(TableViewer userViewer, User user, String name, + ImageDescriptor img) { + super(name, img); + this.userViewer = userViewer; + this.user = user; + } + + @Override + public void run() { + ISelection selection = userViewer.getSelection(); + if (selection.isEmpty()) + return; + + @SuppressWarnings("unchecked") + Iterator it = ((IStructuredSelection) selection).iterator(); + List groups = new ArrayList(); + while (it.hasNext()) { + Group currGroup = it.next(); + groups.add(currGroup); + } + + userAdminWrapper.beginTransactionIfNeeded(); + for (Group group : groups) { + group.removeMember(user); + } + userAdminWrapper.commitOrNotifyTransactionStateChange(); + for (Group group : groups) { + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, group)); + } + } + } + + /** + * Defines the table as being a potential target to add group memberships + * (roles) to this user + */ + private class GroupDropListener extends ViewerDropAdapter { + private static final long serialVersionUID = 2893468717831451621L; + + private final UserAdminWrapper myUserAdminWrapper; + private final User myUser; + + public GroupDropListener(UserAdminWrapper userAdminWrapper, + Viewer userViewer, User user) { + super(userViewer); + this.myUserAdminWrapper = userAdminWrapper; + this.myUser = user; + } + + @Override + public boolean validateDrop(Object target, int operation, + TransferData transferType) { + // Target is always OK in a list only view + // TODO check if not a string + boolean validDrop = true; + return validDrop; + } + + @Override + public void drop(DropTargetEvent event) { + String name = (String) event.data; + UserAdmin myUserAdmin = myUserAdminWrapper.getUserAdmin(); + Role role = myUserAdmin.getRole(name); + // TODO this check should be done before. + if (role.getType() == Role.GROUP) { + // TODO check if the user is already member of this group + + myUserAdminWrapper.beginTransactionIfNeeded(); + Group group = (Group) role; + group.addMember(myUser); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + myUserAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, group)); + } + super.drop(event); + } + + @Override + public boolean performDrop(Object data) { + // userTableViewerCmp.refresh(); + return true; + } + } + + // LOCAL HELPERS + private void refreshFormTitle(User group) { + getManagedForm().getForm().setText( + UserAdminUtils.getProperty(group, LdifName.cn.name())); + } + + /** Appends a section with a title */ + private Section addSection(FormToolkit tk, Composite parent, String title) { + Section section = tk.createSection(parent, Section.TITLE_BAR); + GridData gd = EclipseUiUtils.fillWidth(); + gd.verticalAlignment = PRE_TITLE_INDENT; + section.setLayoutData(gd); + section.setText(title); + // section.getMenu().setVisible(true); + + Composite body = tk.createComposite(section, SWT.WRAP); + body.setLayoutData(EclipseUiUtils.fillAll()); + section.setClient(body); + + return section; + } + + /** Creates label and multiline text. */ + Text createLMT(FormToolkit toolkit, Composite body, String label, + String value) { + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + return text; + } + + /** Creates label and password. */ + Text createLP(FormToolkit toolkit, Composite body, String label, + String value) { + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + /** Creates label and text. */ + Text createLT(FormToolkit toolkit, Composite body, String label, + String value) { + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java new file mode 100644 index 000000000..e4c265461 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.DomainNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.MailLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserDragListener; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.node.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdminEvent; +import org.osgi.service.useradmin.UserAdminListener; + +/** List all users with filter - based on Ldif userAdmin */ +public class UsersView extends ViewPart implements ArgeoNames { + // private final static Log log = LogFactory.getLog(UsersView.class); + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".usersView"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + // UI Objects + private LdifUsersTable userTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + private UserAdminListener listener; + + @Override + public void createPartControl(Composite parent) { + + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + // Define the displayed columns + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); + columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); + // Only show technical DN to admin + if (UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN)) + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 300)); + + // Create and configure the table + userTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + userTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); + userTableViewerCmp.setColumnDefinitions(columnDefs); + userTableViewerCmp.populate(true, false); + + // Links + userViewer = userTableViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); + getViewSite().setSelectionProvider(userViewer); + + // Really? + userTableViewerCmp.refresh(); + + // Drag and drop + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + userViewer.addDragSupport(operations, tt, new UserDragListener( + userViewer)); + + // Register a useradmin listener + listener = new MyUiUAListener(parent.getDisplay()); + userAdminWrapper.addListener(listener); + } + + private class MyUiUAListener extends UiUserAdminListener { + public MyUiUAListener(Display display) { + super(display); + } + + @Override + public void roleChangedToUiThread(UserAdminEvent event) { + if (userViewer != null && !userViewer.getTable().isDisposed()) + refresh(); + } + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 8467999509931900367L; + + private final String[] knownProps = { LdifName.uid.name(), + LdifName.dn.name(), LdifName.cn.name(), + LdifName.givenName.name(), LdifName.sn.name(), + LdifName.mail.name() }; + + public MyUserTableViewer(Composite parent, int style) { + super(parent, style); + } + + @Override + protected List listFilteredElements(String filter) { + Role[] roles; + + try { + StringBuilder builder = new StringBuilder(); + + StringBuilder tmpBuilder = new StringBuilder(); + if (EclipseUiUtils.notEmpty(filter)) + for (String prop : knownProps) { + tmpBuilder.append("("); + tmpBuilder.append(prop); + tmpBuilder.append("=*"); + tmpBuilder.append(filter); + tmpBuilder.append("*)"); + } + if (tmpBuilder.length() > 1) { + builder.append("(&(").append(LdifName.objectClass.name()) + .append("=").append(LdifName.inetOrgPerson.name()) + .append(")(|"); + builder.append(tmpBuilder.toString()); + builder.append("))"); + } else + builder.append("(").append(LdifName.objectClass.name()) + .append("=").append(LdifName.inetOrgPerson.name()) + .append(")"); + roles = userAdminWrapper.getUserAdmin().getRoles( + builder.toString()); + } catch (InvalidSyntaxException e) { + throw new CmsException("Unable to get roles with filter: " + + filter, e); + } + List users = new ArrayList(); + for (Role role : roles) + // if (role.getType() == Role.USER && role.getType() != + // Role.GROUP) + users.add((User) role); + return users; + } + } + + public void refresh() { + userTableViewerCmp.refresh(); + } + + // Override generic view methods + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void setFocus() { + userTableViewerCmp.setFocus(); + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java new file mode 100644 index 000000000..06e8ededa --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java @@ -0,0 +1,15 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.osgi.useradmin.LdifName; +import org.osgi.service.useradmin.User; + +/** Simply declare a label provider that returns the common name of a user */ +public class CommonNameLP extends UserAdminAbstractLP { + private static final long serialVersionUID = 5256703081044911941L; + + @Override + public String getText(User user) { + return UserAdminUtils.getProperty(user, LdifName.cn.name()); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java new file mode 100644 index 000000000..dee40e0d8 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java @@ -0,0 +1,14 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.osgi.service.useradmin.User; + +/** The human friendly domain name for the corresponding user. */ +public class DomainNameLP extends UserAdminAbstractLP { + private static final long serialVersionUID = 5256703081044911941L; + + @Override + public String getText(User user) { + return UserAdminUtils.getDomainName(user); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java new file mode 100644 index 000000000..4d52ca114 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java @@ -0,0 +1,15 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.osgi.useradmin.LdifName; +import org.osgi.service.useradmin.User; + +/** Simply declare a label provider that returns the Primary Mail of a user */ +public class MailLP extends UserAdminAbstractLP { + private static final long serialVersionUID = 8329764452141982707L; + + @Override + public String getText(User user) { + return UserAdminUtils.getProperty(user, LdifName.mail.name()); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java new file mode 100644 index 000000000..125791f4b --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java @@ -0,0 +1,29 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages; +import org.eclipse.swt.graphics.Image; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** Provide a bundle specific image depending on the current user type */ +public class RoleIconLP extends UserAdminAbstractLP { + private static final long serialVersionUID = 6550449442061090388L; + + @Override + public String getText(User user) { + return ""; + } + + @Override + public Image getImage(Object element) { + User user = (User) element; + String dn = user.getName(); + if (dn.endsWith(AuthConstants.ROLES_BASEDN)) + return SecurityAdminImages.ICON_ROLE; + else if (user.getType() == Role.GROUP) + return SecurityAdminImages.ICON_GROUP; + else + return SecurityAdminImages.ICON_USER; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java new file mode 100644 index 000000000..c5eeb473f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java @@ -0,0 +1,66 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; + +import org.argeo.cms.CmsException; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Display; +import org.osgi.service.useradmin.User; + +/** + * Utility class that add font modifications to a column label provider + * depending on the given user properties + */ +public abstract class UserAdminAbstractLP extends ColumnLabelProvider { + private static final long serialVersionUID = 137336765024922368L; + + // private Font italic; + private Font bold; + + @Override + public Font getFont(Object element) { + // Self as bold + try { + LdapName selfUserName = UserAdminUtils.getCurrentUserLdapName(); + String userName = ((User) element).getName(); + LdapName userLdapName = new LdapName(userName); + if (userLdapName.equals(selfUserName)) { + if (bold == null) + bold = JFaceResources.getFontRegistry() + .defaultFontDescriptor().setStyle(SWT.BOLD) + .createFont(Display.getCurrent()); + return bold; + } + } catch (InvalidNameException e) { + throw new CmsException("cannot parse dn for " + element, e); + } + + // Disabled as Italic + // Node userProfile = (Node) elem; + // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) + // return italic; + + return null; + // return super.getFont(element); + } + + @Override + public String getText(Object element) { + User user = (User) element; + return getText(user); + } + + public void setDisplay(Display display) { + // italic = JFaceResources.getFontRegistry().defaultFontDescriptor() + // .setStyle(SWT.ITALIC).createFont(display); + bold = JFaceResources.getFontRegistry().defaultFontDescriptor() + .setStyle(SWT.BOLD).createFont(Display.getCurrent()); + } + + public abstract String getText(User user); +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java new file mode 100644 index 000000000..ccc76f46a --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java @@ -0,0 +1,40 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.osgi.service.useradmin.User; + +/** Default drag listener to modify group and users via the UI */ +public class UserDragListener implements DragSourceListener { + private static final long serialVersionUID = -2074337775033781454L; + private final Viewer viewer; + + public UserDragListener(Viewer viewer) { + this.viewer = viewer; + } + + public void dragStart(DragSourceEvent event) { + // TODO implement finer checks + IStructuredSelection selection = (IStructuredSelection) viewer + .getSelection(); + if (selection.isEmpty() || selection.size() > 1) + event.doit = false; + else + event.doit = true; + } + + public void dragSetData(DragSourceEvent event) { + // TODO Support multiple selection + Object obj = ((IStructuredSelection) viewer.getSelection()) + .getFirstElement(); + if (obj != null) { + User user = (User) obj; + event.data = user.getName(); + } + } + + public void dragFinished(DragSourceEvent event) { + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java new file mode 100644 index 000000000..624ee546d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java @@ -0,0 +1,60 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; + +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.util.useradmin.UserAdminUtils; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.osgi.service.useradmin.User; + +public class UserFilter extends ViewerFilter { + private static final long serialVersionUID = 5082509381672880568L; + + private String searchString; + private boolean showSystemRole = true; + + private final String[] knownProps = { LdifName.dn.name(), + LdifName.cn.name(), LdifName.givenName.name(), LdifName.sn.name(), + LdifName.uid.name(), LdifName.description.name(), + LdifName.mail.name() }; + + public void setSearchText(String s) { + // ensure that the value can be used for matching + if (notEmpty(s)) + searchString = ".*" + s.toLowerCase() + ".*"; + else + searchString = ".*"; + } + + public void setShowSystemRole(boolean showSystemRole) { + this.showSystemRole = showSystemRole; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + User user = (User) element; + if (!showSystemRole + && user.getName().matches( + ".*(" + AuthConstants.ROLES_BASEDN + ")")) + // UserAdminUtils.getProperty(user, LdifName.dn.name()) + // .toLowerCase().endsWith(AuthConstants.ROLES_BASEDN)) + return false; + + if (searchString == null || searchString.length() == 0) + return true; + + if (user.getName().matches(searchString)) + return true; + + for (String key : knownProps) { + String currVal = UserAdminUtils.getProperty(user, key); + if (notEmpty(currVal) + && currVal.toLowerCase().matches(searchString)) + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java new file mode 100644 index 000000000..0d8e8505b --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java @@ -0,0 +1,13 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.osgi.service.useradmin.User; + +/** Simply declare a label provider that returns the username of a user */ +public class UserNameLP extends UserAdminAbstractLP { + private static final long serialVersionUID = 6550449442061090388L; + + @Override + public String getText(User user) { + return user.getName(); + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java new file mode 100644 index 000000000..5ae8463ba --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java @@ -0,0 +1,43 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditorInput; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.User; + +/** + * Default double click listener for the various user tables, will open the + * clicked item in the editor + */ +public class UserTableDefaultDClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + if (evt.getSelection().isEmpty()) + return; + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + User user = (User) obj; + IWorkbenchWindow iww = WorkbenchUiPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow(); + IWorkbenchPage iwp = iww.getActivePage(); + UserEditorInput uei = new UserEditorInput(user.getName()); + + try { + // Works around the fact that dynamic setting of the editor icon + // causes NPE after a login/logout on RAP + if (user instanceof Group) + iwp.openEditor(uei, UserEditor.GROUP_EDITOR_ID); + else + iwp.openEditor(uei, UserEditor.USER_EDITOR_ID); + } catch (PartInitException pie) { + throw new CmsException("Unable to open UserEditor for " + user, pie); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java new file mode 100644 index 000000000..9741d21ae --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java @@ -0,0 +1,74 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import java.util.HashMap; +import java.util.Map; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.ui.AbstractSourceProvider; +import org.eclipse.ui.ISources; + +/** Observe and notify UI on UserTransaction state changes */ +public class UserTransactionProvider extends AbstractSourceProvider { + private final static Log log = LogFactory + .getLog(UserTransactionProvider.class); + + public final static String TRANSACTION_STATE = WorkbenchUiPlugin.PLUGIN_ID + + ".userTransactionState"; + public final static String STATUS_ACTIVE = "status.active"; + public final static String STATUS_NO_TRANSACTION = "status.noTransaction"; + + /* DEPENDENCY INJECTION */ + private UserTransaction userTransaction; + + @Override + public String[] getProvidedSourceNames() { + return new String[] { TRANSACTION_STATE }; + } + + @Override + public Map getCurrentState() { + Map currentState = new HashMap(1); + currentState.put(TRANSACTION_STATE, getInternalCurrentState()); + return currentState; + } + + @Override + public void dispose() { + } + + private String getInternalCurrentState() { + try { + String transactionState; + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + transactionState = STATUS_NO_TRANSACTION; + else + // if (userTransaction.getStatus() == Status.STATUS_ACTIVE) + transactionState = STATUS_ACTIVE; + return transactionState; + } catch (Exception e) { + throw new CmsException("Unable to begin transaction", e); + } + } + + /** Publishes the ability to notify a state change */ + public void fireTransactionStateChange() { + try { + fireSourceChanged(ISources.WORKBENCH, TRANSACTION_STATE, + getInternalCurrentState()); + } catch (Exception e) { + log.warn("Cannot fire transaction state change event. Caught exception: " + + e.getClass().getCanonicalName() + " - " + e.getMessage()); + } + } + + /* DEPENDENCY INJECTION */ + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java new file mode 100644 index 000000000..e502dd462 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.jcr; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; +import javax.jcr.security.AccessControlManager; +import javax.jcr.security.Privilege; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.ChildNodesPage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericNodeEditorInput; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericNodePage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericPropertyPage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodePrivilegesPage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodeVersionHistoryPage; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.editor.FormEditor; + +/** Default form editor for a Jcr {@link Node} */ +public class DefaultNodeEditor extends FormEditor { + private static final long serialVersionUID = 8322127770921612239L; + + // private final static Log log = + // LogFactory.getLog(GenericNodeEditor.class); + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".defaultNodeEditor"; + + private Node currentNode; + + private GenericNodePage genericNodePage; + private GenericPropertyPage genericPropertyPage; + private ChildNodesPage childNodesPage; + private NodePrivilegesPage nodeRightsManagementPage; + private NodeVersionHistoryPage nodeVersionHistoryPage; + + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + super.init(site, input); + GenericNodeEditorInput nei = (GenericNodeEditorInput) getEditorInput(); + currentNode = nei.getCurrentNode(); + this.setPartName(JcrUtils.lastPathElement(nei.getPath())); + } + + @Override + protected void addPages() { + try { + genericPropertyPage = new GenericPropertyPage(this, + WorkbenchUiPlugin.getMessage("genericNodePageTitle"), + currentNode); + addPage(genericPropertyPage); + + childNodesPage = new ChildNodesPage(this, + WorkbenchUiPlugin.getMessage("childNodesPageTitle"), + currentNode); + addPage(childNodesPage); + + AccessControlManager accessControlManager = currentNode + .getSession().getAccessControlManager(); + List privileges = new ArrayList(); + privileges.add(accessControlManager + .privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL)); + if (accessControlManager.hasPrivileges(currentNode.getPath(), + privileges.toArray(new Privilege[0]))) { + nodeRightsManagementPage = new NodePrivilegesPage(this, + WorkbenchUiPlugin + .getMessage("nodeRightsManagementPageTitle"), + currentNode); + addPage(nodeRightsManagementPage); + } + if (currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) { + nodeVersionHistoryPage = new NodeVersionHistoryPage(this, + WorkbenchUiPlugin + .getMessage("nodeVersionHistoryPageTitle"), + currentNode); + addPage(nodeVersionHistoryPage); + } + + privileges = new ArrayList(); + privileges.add(accessControlManager + .privilegeFromName(Privilege.JCR_ALL)); + if (accessControlManager.hasPrivileges(currentNode.getPath(), + privileges.toArray(new Privilege[0]))) { + genericNodePage = new GenericNodePage( + this, + WorkbenchUiPlugin.getMessage("propertyEditorPageTitle"), + currentNode); + addPage(genericNodePage); + } + + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot get node info for " + + currentNode, e); + } catch (PartInitException e) { + throw new EclipseUiException("Cannot add page " + + "on node editor for " + currentNode, e); + } + } + + @Override + public void doSaveAs() { + // unused compulsory method + } + + @Override + public void doSave(IProgressMonitor monitor) { + try { + // Automatically commit all pages of the editor + commitPages(true); + firePropertyChange(PROP_DIRTY); + } catch (Exception e) { + throw new EclipseUiException("Error while saving node", e); + } + + } + + @Override + public boolean isSaveAsAllowed() { + return true; + } + + Node getCurrentNode() { + return currentNode; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java new file mode 100644 index 000000000..7c7f2b97b --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.jcr; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.AbstractJcrQueryEditor; +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; + +/** Enables end user to type and execute any JCR query. */ +public class GenericJcrQueryEditor extends AbstractJcrQueryEditor { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".genericJcrQueryEditor"; + + 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() { + private static final long serialVersionUID = -918256291554301699L; + + 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/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java new file mode 100644 index 000000000..e012e0e05 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.jcr; + +import java.util.List; + +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; +import javax.jcr.Value; +import javax.jcr.observation.Event; +import javax.jcr.observation.EventListener; +import javax.jcr.observation.ObservationManager; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.GenericNodeDoubleClickListener; +import org.argeo.cms.ui.workbench.internal.jcr.JcrBrowserUtils; +import org.argeo.cms.ui.workbench.internal.jcr.NodeContentProvider; +import org.argeo.cms.ui.workbench.internal.jcr.NodeLabelProvider; +import org.argeo.cms.ui.workbench.internal.jcr.PropertiesContentProvider; +import org.argeo.cms.ui.workbench.internal.jcr.model.SingleJcrNodeElem; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; +import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer; +import org.argeo.jcr.RepositoryRegister; +import org.argeo.node.security.Keyring; +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; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +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.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.part.ViewPart; + +/** + * Basic View to display a sash form to browse a JCR compliant multiple + * repository environment + */ +public class JcrBrowserView extends ViewPart { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".jcrBrowserView"; + private boolean sortChildNodes = true; + + /* DEPENDENCY INJECTION */ + private Keyring keyring; + private RepositoryRegister repositoryRegister; + private RepositoryFactory repositoryFactory; + private Repository nodeRepository; + + // Current user session on the "Argeo node" default workspace + private Session userSession; + + // This page widgets + private TreeViewer nodesViewer; + private NodeContentProvider nodeContentProvider; + private TableViewer propertiesViewer; + private EventListener resultsObserver; + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new FillLayout()); + SashForm sashForm = new SashForm(parent, SWT.VERTICAL); + sashForm.setSashWidth(4); + sashForm.setLayout(new FillLayout()); + + // Create the tree on top of the view + Composite top = new Composite(sashForm, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + top.setLayout(gl); + + try { + this.userSession = this.nodeRepository.login(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot open user session", e); + } + + nodeContentProvider = new NodeContentProvider(userSession, keyring, + repositoryRegister, repositoryFactory, sortChildNodes); + + // nodes viewer + nodesViewer = createNodeViewer(top, nodeContentProvider); + + // context menu : it is completely defined in the plugin.xml file. + MenuManager menuManager = new MenuManager(); + Menu menu = menuManager.createContextMenu(nodesViewer.getTree()); + + nodesViewer.getTree().setMenu(menu); + getSite().registerContextMenu(menuManager, nodesViewer); + getSite().setSelectionProvider(nodesViewer); + + nodesViewer.setInput(getViewSite()); + + // Create the property viewer on the bottom + Composite bottom = new Composite(sashForm, SWT.NONE); + bottom.setLayout(new GridLayout(1, false)); + propertiesViewer = createPropertiesViewer(bottom); + + sashForm.setWeights(getWeights()); + nodesViewer.setComparer(new NodeViewerComparer()); + } + + public void refresh(Object obj) { + // Enable full refresh from a command when no element of the tree is + // selected + if (obj == null) { + Object[] elements = nodeContentProvider.getElements(null); + for (Object el : elements) { + if (el instanceof TreeParent) + JcrBrowserUtils.forceRefreshIfNeeded((TreeParent) el); + getNodeViewer().refresh(el); + } + } else + getNodeViewer().refresh(obj); + } + + /** + * To be overridden to adapt size of form and result frames. + */ + protected int[] getWeights() { + return new int[] { 70, 30 }; + } + + protected TreeViewer createNodeViewer(Composite parent, + final ITreeContentProvider nodeContentProvider) { + + final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI); + + tmpNodeViewer.getTree().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + tmpNodeViewer.setContentProvider(nodeContentProvider); + tmpNodeViewer.setLabelProvider(new NodeLabelProvider()); + tmpNodeViewer + .addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + if (!event.getSelection().isEmpty()) { + IStructuredSelection sel = (IStructuredSelection) event + .getSelection(); + Object firstItem = sel.getFirstElement(); + if (firstItem instanceof SingleJcrNodeElem) + propertiesViewer + .setInput(((SingleJcrNodeElem) firstItem) + .getNode()); + } else { + propertiesViewer.setInput(getViewSite()); + } + } + }); + + resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay()); + if (keyring != null) + try { + ObservationManager observationManager = userSession + .getWorkspace().getObservationManager(); + observationManager.addEventListener(resultsObserver, + Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/", + true, null, null, false); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot register listeners", e); + } + + tmpNodeViewer + .addDoubleClickListener(new GenericNodeDoubleClickListener( + tmpNodeViewer)); + return tmpNodeViewer; + } + + protected TableViewer createPropertiesViewer(Composite parent) { + propertiesViewer = new TableViewer(parent); + propertiesViewer.getTable().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + propertiesViewer.getTable().setHeaderVisible(true); + propertiesViewer.setContentProvider(new PropertiesContentProvider()); + TableViewerColumn col = new TableViewerColumn(propertiesViewer, + SWT.NONE); + col.getColumn().setText("Name"); + col.getColumn().setWidth(200); + col.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -6684361063107478595L; + + public String getText(Object element) { + try { + return ((Property) element).getName(); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected exception in label provider", e); + } + } + }); + col = new TableViewerColumn(propertiesViewer, SWT.NONE); + col.getColumn().setText("Value"); + col.getColumn().setWidth(400); + col.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -8201994187693336657L; + + public String getText(Object element) { + try { + Property property = (Property) element; + if (property.getType() == PropertyType.BINARY) + return ""; + else if (property.isMultiple()) { + StringBuffer buf = new StringBuffer("["); + Value[] values = property.getValues(); + for (int i = 0; i < values.length; i++) { + if (i != 0) + buf.append(", "); + buf.append(values[i].getString()); + } + buf.append(']'); + return buf.toString(); + } else + return property.getValue().getString(); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected exception in label provider", e); + } + } + }); + col = new TableViewerColumn(propertiesViewer, SWT.NONE); + col.getColumn().setText("Type"); + col.getColumn().setWidth(200); + col.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -6009599998150286070L; + + public String getText(Object element) { + try { + return PropertyType.nameFromValue(((Property) element) + .getType()); + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unexpected exception in label provider", e); + } + } + }); + propertiesViewer.setInput(getViewSite()); + return propertiesViewer; + } + + @Override + public void dispose() { + super.dispose(); + } + + protected TreeViewer getNodeViewer() { + return nodesViewer; + } + + /** + * Resets the tree content provider + * + * @param sortChildNodes + * if true the content provider will use a comparer to sort nodes + * that might slow down the display + * */ + public void setSortChildNodes(boolean sortChildNodes) { + this.sortChildNodes = sortChildNodes; + ((NodeContentProvider) nodesViewer.getContentProvider()) + .setSortChildren(sortChildNodes); + nodesViewer.setInput(getViewSite()); + } + + /** Notifies the current view that a node has been added */ + public void nodeAdded(TreeParent parentNode) { + // insure that Ui objects have been correctly created: + JcrBrowserUtils.forceRefreshIfNeeded(parentNode); + getNodeViewer().refresh(parentNode); + getNodeViewer().expandToLevel(parentNode, 1); + } + + /** Notifies the current view that a node has been removed */ + 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) { + super(display); + } + + @Override + protected Boolean willProcessInUiThread(List events) + throws RepositoryException { + for (Event event : events) { + if (getLog().isTraceEnabled()) + getLog().debug("Received event " + event); + String path = event.getPath(); + int index = path.lastIndexOf('/'); + String propertyName = path.substring(index + 1); + if (getLog().isTraceEnabled()) + getLog().debug("Concerned property " + propertyName); + } + return false; + } + + protected void onEventInUiThread(List events) + throws RepositoryException { + if (getLog().isTraceEnabled()) + getLog().trace("Refresh result list"); + nodesViewer.refresh(); + } + + } + + public boolean getSortChildNodes() { + return sortChildNodes; + } + + @Override + public void setFocus() { + getNodeViewer().getTree().setFocus(); + } + + /* DEPENDENCY INJECTION */ + public void setRepositoryRegister(RepositoryRegister repositoryRegister) { + this.repositoryRegister = repositoryRegister; + } + + public void setKeyring(Keyring keyring) { + this.keyring = keyring; + } + + public void setRepositoryFactory(RepositoryFactory repositoryFactory) { + this.repositoryFactory = repositoryFactory; + } + + public void setNodeRepository(Repository nodeRepository) { + this.nodeRepository = nodeRepository; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrImages.java new file mode 100644 index 000000000..d7f7b60c7 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrImages.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.jcr; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** Shared icons. */ +public class JcrImages { + public final static Image NODE = WorkbenchUiPlugin.getImageDescriptor( + "icons/node.gif").createImage(); + public final static Image FOLDER = WorkbenchUiPlugin.getImageDescriptor( + "icons/folder.gif").createImage(); + public final static Image FILE = WorkbenchUiPlugin.getImageDescriptor( + "icons/file.gif").createImage(); + public final static Image BINARY = WorkbenchUiPlugin.getImageDescriptor( + "icons/binary.png").createImage(); + public final static Image HOME = WorkbenchUiPlugin.getImageDescriptor( + "icons/home.gif").createImage(); + public final static Image SORT = WorkbenchUiPlugin.getImageDescriptor( + "icons/sort.gif").createImage(); + public final static Image REMOVE = WorkbenchUiPlugin.getImageDescriptor( + "icons/remove.gif").createImage(); + + public final static Image REPOSITORIES = WorkbenchUiPlugin + .getImageDescriptor("icons/repositories.gif").createImage(); + public final static Image REPOSITORY_DISCONNECTED = WorkbenchUiPlugin + .getImageDescriptor("icons/repository_disconnected.gif") + .createImage(); + public final static Image REPOSITORY_CONNECTED = WorkbenchUiPlugin + .getImageDescriptor("icons/repository_connected.gif").createImage(); + public final static Image REMOTE_DISCONNECTED = WorkbenchUiPlugin + .getImageDescriptor("icons/remote_disconnected.gif").createImage(); + public final static Image REMOTE_CONNECTED = WorkbenchUiPlugin + .getImageDescriptor("icons/remote_connected.gif").createImage(); + public final static Image WORKSPACE_DISCONNECTED = WorkbenchUiPlugin + .getImageDescriptor("icons/workspace_disconnected.png") + .createImage(); + public final static Image WORKSPACE_CONNECTED = WorkbenchUiPlugin + .getImageDescriptor("icons/workspace_connected.png").createImage(); + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrPreferenceStore.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrPreferenceStore.java new file mode 100644 index 000000000..d1917d908 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrPreferenceStore.java @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.jcr; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Properties; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.version.VersionManager; + +import org.apache.commons.io.IOUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.argeo.node.ArgeoNames; +import org.argeo.node.ArgeoTypes; +import org.argeo.node.NodeUtils; +import org.eclipse.jface.preference.PreferenceStore; +import org.osgi.framework.BundleContext; + +/** + * Persist preferences as key/value pairs under ~/argeo:preferences.
+ * TODO: better integrate JCR and Eclipse:
+ * - typing
+ * - use eclipse preferences
+ * - better integrate with ScopedPreferenceStore provided by RAP + */ +public class JcrPreferenceStore extends PreferenceStore implements ArgeoNames { + private static final long serialVersionUID = 1854011367784598758L; + + private Session session; + private BundleContext bundleContext; + + /** Retrieves the preference node */ + protected Node getPreferenceNode() { + try { + if (session.hasPendingChanges()) + session.save(); + Node userHome = NodeUtils.getUserHome(session); + if (userHome == null) + throw new EclipseUiException("No user home for " + + session.getUserID()); + Node preferences; + if (!userHome.hasNode(ARGEO_PREFERENCES)) { + preferences = userHome.addNode(ARGEO_PREFERENCES); + preferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE); + session.save(); + } else + preferences = userHome.getNode(ARGEO_PREFERENCES); + + String pluginPreferencesName = bundleContext.getBundle() + .getSymbolicName(); + Node pluginPreferences; + if (!preferences.hasNode(pluginPreferencesName)) { + VersionManager vm = session.getWorkspace().getVersionManager(); + vm.checkout(preferences.getPath()); + pluginPreferences = preferences.addNode(pluginPreferencesName); + pluginPreferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE); + session.save(); + vm.checkin(preferences.getPath()); + } else + pluginPreferences = preferences.getNode(pluginPreferencesName); + return pluginPreferences; + } catch (RepositoryException e) { + e.printStackTrace(); + JcrUtils.discardQuietly(session); + throw new EclipseUiException("Cannot retrieve preferences", e); + } + + } + + @Override + public void load() throws IOException { + ByteArrayOutputStream out = null; + ByteArrayInputStream in = null; + try { + Properties props = new Properties(); + PropertyIterator it = getPreferenceNode().getProperties(); + while (it.hasNext()) { + Property p = it.nextProperty(); + if (!p.isMultiple() && !p.getDefinition().isProtected()) { + props.setProperty(p.getName(), p.getValue().getString()); + } + } + out = new ByteArrayOutputStream(); + props.store(out, ""); + in = new ByteArrayInputStream(out.toByteArray()); + load(in); + } catch (Exception e) { + e.printStackTrace(); + throw new EclipseUiException("Cannot load preferences", e); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } + } + + @Override + public void save() throws IOException { + ByteArrayOutputStream out = null; + ByteArrayInputStream in = null; + Node pluginPreferences = null; + try { + out = new ByteArrayOutputStream(); + save(out, ""); + in = new ByteArrayInputStream(out.toByteArray()); + Properties props = new Properties(); + props.load(in); + pluginPreferences = getPreferenceNode(); + VersionManager vm = pluginPreferences.getSession().getWorkspace() + .getVersionManager(); + vm.checkout(pluginPreferences.getPath()); + for (Object key : props.keySet()) { + String name = key.toString(); + String value = props.getProperty(name); + pluginPreferences.setProperty(name, value); + } + JcrUtils.updateLastModified(pluginPreferences); + pluginPreferences.getSession().save(); + vm.checkin(pluginPreferences.getPath()); + } catch (Exception e) { + JcrUtils.discardUnderlyingSessionQuietly(pluginPreferences); + throw new EclipseUiException("Cannot save preferences", e); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } + } + + public void init() { + try { + load(); + } catch (IOException e) { + throw new EclipseUiException("Cannot initialize preference store", e); + } + } + + public void setSession(Session session) { + this.session = session; + } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java new file mode 100644 index 000000000..4bbe7a5a6 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java @@ -0,0 +1,46 @@ +package org.argeo.cms.ui.workbench.osgi; + +import org.argeo.eclipse.ui.TreeParent; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** A tree element representing a {@link Bundle} */ +class BundleNode extends TreeParent { + private final Bundle bundle; + + public BundleNode(Bundle bundle) { + this(bundle, false); + } + + @SuppressWarnings("rawtypes") + public BundleNode(Bundle bundle, boolean hasChildren) { + super(bundle.getSymbolicName()); + this.bundle = bundle; + + if (hasChildren) { + // REFERENCES + ServiceReference[] usedServices = bundle.getServicesInUse(); + if (usedServices != null) { + for (ServiceReference sr : usedServices) { + if (sr != null) + addChild(new ServiceReferenceNode(sr, false)); + } + } + + // SERVICES + ServiceReference[] registeredServices = bundle + .getRegisteredServices(); + if (registeredServices != null) { + for (ServiceReference sr : registeredServices) { + if (sr != null) + addChild(new ServiceReferenceNode(sr, true)); + } + } + } + + } + + Bundle getBundle() { + return bundle; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java new file mode 100644 index 000000000..bb1531997 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java @@ -0,0 +1,147 @@ +//package org.argeo.eclipse.ui.workbench.osgi; +//public class BundlesView {} + +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.osgi; + +import java.util.Comparator; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.ColumnViewerComparator; +import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; +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.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Overview of the bundles as a table. Equivalent to Equinox 'ss' console + * command. + */ +public class BundlesView extends ViewPart { + private TableViewer viewer; + + @Override + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent); + viewer.setContentProvider(new BundleContentProvider()); + viewer.getTable().setHeaderVisible(true); + + EclipseUiSpecificUtils.enableToolTipSupport(viewer); + + // ID + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(30); + column.getColumn().setText("ID"); + column.getColumn().setAlignment(SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -3122136344359358605L; + + public String getText(Object element) { + return Long.toString(((Bundle) element).getBundleId()); + } + }); + new ColumnViewerComparator(column, new Comparator() { + public int compare(Bundle o1, Bundle o2) { + return (int) (o1.getBundleId() - o2.getBundleId()); + } + }); + + // State + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(18); + column.getColumn().setText("State"); + column.setLabelProvider(new StateLabelProvider()); + new ColumnViewerComparator(column, new Comparator() { + public int compare(Bundle o1, Bundle o2) { + return o1.getState() - o2.getState(); + } + }); + + // Symbolic name + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(250); + column.getColumn().setText("Symbolic Name"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -4280840684440451080L; + + public String getText(Object element) { + return ((Bundle) element).getSymbolicName(); + } + }); + new ColumnViewerComparator(column, new Comparator() { + public int compare(Bundle o1, Bundle o2) { + return o1.getSymbolicName().compareTo(o2.getSymbolicName()); + } + }); + + // Version + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(150); + column.getColumn().setText("Version"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 6871926308708629989L; + + public String getText(Object element) { + Bundle bundle = (org.osgi.framework.Bundle) element; + return bundle.getVersion().toString(); + } + }); + new ColumnViewerComparator(column, new Comparator() { + public int compare(Bundle o1, Bundle o2) { + return o1.getVersion().compareTo(o2.getVersion()); + } + }); + + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle() + .getBundleContext()); + + } + + @Override + public void setFocus() { + if (viewer != null) + viewer.getControl().setFocus(); + } + + /** Content provider managing the array of bundles */ + private static class BundleContentProvider implements + IStructuredContentProvider { + private static final long serialVersionUID = -8533792785725875977L; + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof BundleContext) { + BundleContext bc = (BundleContext) inputElement; + return bc.getBundles(); + } + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java new file mode 100644 index 000000000..235261a58 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.osgi; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.TreeParent; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** The OSGi runtime from a module perspective. */ +public class ModulesView extends ViewPart { + private TreeViewer viewer; + + @Override + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(new ModulesContentProvider()); + viewer.setLabelProvider(new ModulesLabelProvider()); + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle() + .getBundleContext()); + } + + @Override + public void setFocus() { + viewer.getTree().setFocus(); + } + + private class ModulesContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = 3819934804640641721L; + + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof BundleContext) { + BundleContext bundleContext = (BundleContext) parentElement; + Bundle[] bundles = bundleContext.getBundles(); + + List modules = new ArrayList(); + for (Bundle bundle : bundles) { + if (bundle.getState() == Bundle.ACTIVE) + modules.add(new BundleNode(bundle, true)); + } + return modules.toArray(); + } else if (parentElement instanceof TreeParent) { + return ((TreeParent) parentElement).getChildren(); + } else { + return null; + } + } + + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof TreeParent) { + return ((TreeParent) element).hasChildren(); + } + return false; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + private class ModulesLabelProvider extends StateLabelProvider { + private static final long serialVersionUID = 5290046145534824722L; + + @Override + public String getText(Object element) { + if (element instanceof BundleNode) + return element.toString() + " [" + + ((BundleNode) element).getBundle().getBundleId() + + "]"; + return element.toString(); + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java new file mode 100644 index 000000000..a7f9a5335 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.osgi; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.TreeParent; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.ExportedPackage; +import org.osgi.service.packageadmin.PackageAdmin; + +/** Experimental The OSGi runtime from a module perspective. */ +@SuppressWarnings({ "deprecation", "rawtypes", "unchecked" }) +public class MultiplePackagesView extends ViewPart { + private TreeViewer viewer; + private PackageAdmin packageAdmin; + private Comparator epc = new Comparator() { + public int compare(ExportedPackage o1, ExportedPackage o2) { + if (!o1.getName().equals(o2.getName())) + return o1.getName().compareTo(o2.getName()); + else + return o1.getVersion().compareTo(o2.getVersion()); + } + }; + + @Override + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(new ModulesContentProvider()); + viewer.setLabelProvider(new LabelProvider()); + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle() + .getBundleContext()); + } + + @Override + public void setFocus() { + viewer.getTree().setFocus(); + } + + private class ModulesContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = 3819934804640641721L; + + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof BundleContext) { + BundleContext bundleContext = (BundleContext) parentElement; + Bundle[] bundles = bundleContext.getBundles(); + + // scan packages + ServiceReference paSr = bundleContext + .getServiceReference(PackageAdmin.class.getName()); + // TODO: make a cleaner referencing + packageAdmin = (PackageAdmin) bundleContext.getService(paSr); + + Map> imported = new HashMap>(); + Map> packages = new TreeMap>(); + for (Bundle bundle : bundles) { + processBundle(bundle, imported, packages); + } + + List multiplePackages = new ArrayList(); + for (String packageName : packages.keySet()) { + Set pkgs = packages.get(packageName); + if (pkgs.size() > 1) { + MultiplePackagesNode mpn = new MultiplePackagesNode( + packageName, pkgs); + multiplePackages.add(mpn); + } + } + + return multiplePackages.toArray(); + } else if (parentElement instanceof TreeParent) { + return ((TreeParent) parentElement).getChildren(); + } else { + return null; + } + } + + protected void processBundle(Bundle bundle, + Map> imported, + Map> packages) { + ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle); + if (pkgs == null) + return; + for (ExportedPackage pkg : pkgs) { + if (!packages.containsKey(pkg.getName())) + packages.put(pkg.getName(), new TreeSet( + epc)); + Set expPackages = packages.get(pkg.getName()); + expPackages.add(pkg); + + // imported + for (Bundle b : pkg.getImportingBundles()) { + if (bundle.getBundleId() != b.getBundleId()) { + if (!imported.containsKey(b)) { + imported.put(b, new TreeSet(epc)); + } + Set impPackages = imported.get(b); + impPackages.add(pkg); + } + } + } + } + + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof TreeParent) { + return ((TreeParent) element).hasChildren(); + } + return false; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + private class MultiplePackagesNode extends TreeParent { + public MultiplePackagesNode(String packageName, + Set exportedPackages) { + super(packageName); + for (ExportedPackage pkg : exportedPackages) { + addChild(new ExportedPackageNode(pkg)); + } + } + } + + private class ExportedPackageNode extends TreeParent { + public ExportedPackageNode(ExportedPackage exportedPackage) { + super(exportedPackage.getName() + " - " + + exportedPackage.getVersion() + " (" + + exportedPackage.getExportingBundle() + ")"); + for (Bundle bundle : exportedPackage.getImportingBundles()) { + addChild(new BundleNode(bundle, true)); + } + } + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java new file mode 100644 index 000000000..1233e11e6 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.osgi; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** Shared icons. */ +public class OsgiExplorerImages { + public final static Image INSTALLED = WorkbenchUiPlugin.getImageDescriptor( + "icons/installed.gif").createImage(); + public final static Image RESOLVED = WorkbenchUiPlugin.getImageDescriptor( + "icons/resolved.gif").createImage(); + public final static Image STARTING = WorkbenchUiPlugin.getImageDescriptor( + "icons/starting.gif").createImage(); + public final static Image ACTIVE = WorkbenchUiPlugin.getImageDescriptor( + "icons/active.gif").createImage(); + public final static Image SERVICE_PUBLISHED = WorkbenchUiPlugin + .getImageDescriptor("icons/service_published.gif").createImage(); + public final static Image SERVICE_REFERENCED = WorkbenchUiPlugin + .getImageDescriptor("icons/service_referenced.gif").createImage(); +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java new file mode 100644 index 000000000..6b4972d6d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java @@ -0,0 +1,46 @@ +package org.argeo.cms.ui.workbench.osgi; + +import org.argeo.eclipse.ui.TreeParent; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** A tree element representing a {@link ServiceReference} */ +@SuppressWarnings({ "rawtypes" }) +class ServiceReferenceNode extends TreeParent { + private final ServiceReference serviceReference; + private final boolean published; + + public ServiceReferenceNode(ServiceReference serviceReference, + boolean published) { + super(serviceReference.toString()); + this.serviceReference = serviceReference; + this.published = published; + + if (isPublished()) { + Bundle[] usedBundles = serviceReference.getUsingBundles(); + if (usedBundles != null) { + for (Bundle b : usedBundles) { + if (b != null) + addChild(new BundleNode(b)); + } + } + } else { + Bundle provider = serviceReference.getBundle(); + addChild(new BundleNode(provider)); + } + + for (String key : serviceReference.getPropertyKeys()) { + addChild(new TreeParent(key + "=" + + serviceReference.getProperty(key))); + } + + } + + public ServiceReference getServiceReference() { + return serviceReference; + } + + public boolean isPublished() { + return published; + } +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java new file mode 100644 index 000000000..0edd6a00f --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java @@ -0,0 +1,82 @@ +package org.argeo.cms.ui.workbench.osgi; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Image; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; + +/** Label provider showing the sate of bundles */ +class StateLabelProvider extends ColumnLabelProvider { + private static final long serialVersionUID = -7885583135316000733L; + + @Override + public Image getImage(Object element) { + int state; + if (element instanceof Bundle) + state = ((Bundle) element).getState(); + else if (element instanceof BundleNode) + state = ((BundleNode) element).getBundle().getState(); + else if (element instanceof ServiceReferenceNode) + if (((ServiceReferenceNode) element).isPublished()) + return OsgiExplorerImages.SERVICE_PUBLISHED; + else + return OsgiExplorerImages.SERVICE_REFERENCED; + else + return null; + + switch (state) { + case Bundle.UNINSTALLED: + return OsgiExplorerImages.INSTALLED; + case Bundle.INSTALLED: + return OsgiExplorerImages.INSTALLED; + case Bundle.RESOLVED: + return OsgiExplorerImages.RESOLVED; + case Bundle.STARTING: + return OsgiExplorerImages.STARTING; + case Bundle.STOPPING: + return OsgiExplorerImages.STARTING; + case Bundle.ACTIVE: + return OsgiExplorerImages.ACTIVE; + default: + return null; + } + } + + @Override + public String getText(Object element) { + return null; + } + + @Override + public String getToolTipText(Object element) { + Bundle bundle = (Bundle) element; + Integer state = bundle.getState(); + switch (state) { + case Bundle.UNINSTALLED: + return "UNINSTALLED"; + case Bundle.INSTALLED: + return "INSTALLED"; + case Bundle.RESOLVED: + return "RESOLVED"; + case Bundle.STARTING: + String activationPolicy = bundle.getHeaders() + .get(Constants.BUNDLE_ACTIVATIONPOLICY).toString(); + + // .get("Bundle-ActivationPolicy").toString(); + // FIXME constant triggers the compilation failure + if (activationPolicy != null + && activationPolicy.equals(Constants.ACTIVATION_LAZY)) + // && activationPolicy.equals("lazy")) + // FIXME constant triggers the compilation failure + // && activationPolicy.equals(Constants.ACTIVATION_LAZY)) + return "<>"; + return "STARTING"; + case Bundle.STOPPING: + return "STOPPING"; + case Bundle.ACTIVE: + return "ACTIVE"; + default: + return null; + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java new file mode 100644 index 000000000..c3e3ca744 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.useradmin; + +import java.util.ArrayList; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.node.ArgeoLogger; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** + * Display log lines for all users with a virtual table. + */ +public class AdminLogView extends ViewPart { + public static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".adminLogView"; + + private TableViewer viewer; + + private LogContentProvider logContentProvider; + private ArgeoLogger argeoLogger; + + @Override + public void createPartControl(Composite parent) { + // FIXME doesn't return a monospace font in RAP + Font font = JFaceResources.getTextFont(); + Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + table.setFont(font); + + viewer = new TableViewer(table); + viewer.setLabelProvider(new LabelProvider()); + logContentProvider = new LogContentProvider(viewer) { + private static final long serialVersionUID = -3401776448301180724L; + + @Override + protected StringBuffer prefix(String username, Long timestamp, + String level, String category, String thread) { + return super + .prefix(username, timestamp, level, category, thread) + .append(norm(level, 5)) + .append(' ') + .append(norm(username != null ? username + : "", 16)).append(' '); + } + }; + viewer.setContentProvider(logContentProvider); + // viewer.setUseHashlookup(true); + viewer.setInput(new ArrayList()); + + if (argeoLogger != null) + argeoLogger.registerForAll(logContentProvider, 1000, true); + } + + @Override + public void setFocus() { + viewer.getTable().setFocus(); + } + + @Override + public void dispose() { + if (argeoLogger != null) + argeoLogger.unregisterForAll(logContentProvider); + } + + public void setArgeoLogger(ArgeoLogger argeoLogger) { + this.argeoLogger = argeoLogger; + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java new file mode 100644 index 000000000..6df7ad515 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.useradmin; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import org.argeo.node.ArgeoLogListener; +import org.eclipse.jface.viewers.ILazyContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; + +/** A content provider maintaining an array of lines */ +class LogContentProvider implements ILazyContentProvider, ArgeoLogListener { + private static final long serialVersionUID = -2084872367738339721L; + + private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + private final Long start; + /** current - start = line number. first line is number '1' */ + private Long current; + + // TODO make it configurable + private final Integer maxLineBufferSize = 10 * 1000; + + private final TableViewer viewer; + private LinkedList lines; + + public LogContentProvider(TableViewer viewer) { + this.viewer = viewer; + start = System.currentTimeMillis(); + lines = new LinkedList(); + current = start; + } + + public synchronized void dispose() { + lines.clear(); + lines = null; + } + + @SuppressWarnings("unchecked") + public synchronized void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + List lin = (List) newInput; + if (lin == null) + return; + for (String line : lin) { + addLine(line); + } + this.viewer.setItemCount(lines.size()); + } + + public void updateElement(int index) { + viewer.replace(lines.get(index), index); + } + + public synchronized void appendLog(String username, Long timestamp, + String level, String category, String thread, Object msg, + String[] exception) { + // check if valid + if (lines == null) + return; + + String message = msg.toString(); + int count = 0; + String prefix = prefix(username, timestamp, level, category, thread) + .toString(); + // String suffix = suffix(username, timestamp, level, category, thread); + for (String line : message.split("\n")) { + addLine(count == 0 ? prefix + line : line); + count++; + } + + if (exception != null) { + for (String ste : exception) { + addLine(ste); + } + } + + viewer.getTable().getDisplay().asyncExec(new Runnable() { + public void run() { + if (lines == null) + return; + viewer.setItemCount(lines.size()); + // doesn't work with syncExec + scrollToLastLine(); + } + }); + } + + protected StringBuffer prefix(String username, Long timestamp, + String level, String category, String thread) { + StringBuffer buf = new StringBuffer(""); + buf.append(dateFormat.format(new Date(timestamp))).append(" "); + // buf.append(level).append(" "); + return buf; + } + + /** Normalize string to the given size */ + protected String norm(String str, Integer size) { + int length = str.length(); + if (length == size) + return str; + else if (length > size) + return str.substring(0, size); + else { + char[] arr = new char[size - length]; + Arrays.fill(arr, ' '); + return str + new String(arr); + } + } + + // protected String suffix(String username, Long timestamp, String level, + // String category, String thread) { + // return ""; + // } + + /** Scroll to the last line */ + protected synchronized void scrollToLastLine() { + // we try to show last line with two methods + // viewer.reveal(lines.peekLast()); + + Table table = viewer.getTable(); + TableItem ti = table.getItem(table.getItemCount() - 1); + table.showItem(ti); + } + + protected synchronized LogLine addLine(String line) { + // check for maximal size and purge if necessary + while (lines.size() >= maxLineBufferSize) { + for (int i = 0; i < maxLineBufferSize / 10; i++) { + lines.poll(); + } + } + + current++; + LogLine logLine = new LogLine(current, line); + lines.add(logLine); + return logLine; + } + + private class LogLine { + private Long linenumber; + private String message; + + public LogLine(Long linenumber, String message) { + this.linenumber = linenumber; + this.message = message; + } + + @Override + public int hashCode() { + return linenumber.intValue(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LogLine) + return ((LogLine) obj).linenumber.equals(linenumber); + else + return false; + } + + @Override + public String toString() { + return message; + } + + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java new file mode 100644 index 000000000..07c808d3e --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.useradmin; + +import java.util.ArrayList; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.node.ArgeoLogListener; +import org.argeo.node.ArgeoLogger; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** + * Display log lines with a virtual table. Register and unregisters a + * {@link ArgeoLogListener} via OSGi services. + */ +public class LogView extends ViewPart { + public static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".logView"; + + private TableViewer viewer; + + private LogContentProvider logContentProvider; + private ArgeoLogger argeoLogger; + + @Override + public void createPartControl(Composite parent) { + Font font = JFaceResources.getTextFont(); + Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + table.setFont(font); + + viewer = new TableViewer(table); + viewer.setLabelProvider(new LabelProvider()); + logContentProvider = new LogContentProvider(viewer); + viewer.setContentProvider(logContentProvider); + // viewer.setUseHashlookup(true); + viewer.setInput(new ArrayList()); + + if (argeoLogger != null) + argeoLogger.register(logContentProvider, 1000); + } + + @Override + public void setFocus() { + viewer.getTable().setFocus(); + } + + @Override + public void dispose() { + if (argeoLogger != null) + argeoLogger.unregister(logContentProvider); + } + + public void setArgeoLogger(ArgeoLogger argeoLogger) { + this.argeoLogger = argeoLogger; + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/PickUpUserDialog.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/PickUpUserDialog.java new file mode 100644 index 000000000..aa2312829 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/PickUpUserDialog.java @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.useradmin; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.cms.ui.workbench.internal.useradmin.UsersUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.osgi.useradmin.LdifName; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.FillLayout; +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.Control; +import org.eclipse.swt.widgets.Shell; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Dialog with a user (or group) list to pick up one */ +public class PickUpUserDialog extends TrayDialog { + private static final long serialVersionUID = -1420106871173920369L; + + // Business objects + private final UserAdmin userAdmin; + private User selectedUser; + + // this page widgets and UI objects + private String title; + private LdifUsersTable userTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + /** + * A dialog to pick up a group or a user, showing a table with default + * columns + */ + public PickUpUserDialog(Shell parentShell, String title, UserAdmin userAdmin) { + super(parentShell); + this.title = title; + this.userAdmin = userAdmin; + + columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_ICON), "", + 24, 24)); + columnDefs.add(new ColumnDefinition( + new UserLP(UserLP.COL_DISPLAY_NAME), "Common Name", 150, 100)); + columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DOMAIN), + "Domain", 100, 120)); + columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DN), + "Distinguished Name", 300, 100)); + } + + /** A dialog to pick up a group or a user */ + public PickUpUserDialog(Shell parentShell, String title, + UserAdmin userAdmin, List columnDefs) { + super(parentShell); + this.title = title; + this.userAdmin = userAdmin; + this.columnDefs = columnDefs; + } + + @Override + protected void okPressed() { + if (getSelected() == null) + MessageDialog.openError(getShell(), "No user chosen", + "Please, choose a user or press Cancel."); + else + super.okPressed(); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogArea = (Composite) super.createDialogArea(parent); + dialogArea.setLayout(new FillLayout()); + + Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS); + bodyCmp.setLayout(new GridLayout()); + + // Create and configure the table + userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + + userTableViewerCmp.setColumnDefinitions(columnDefs); + userTableViewerCmp.populateWithStaticFilters(false, false); + GridData gd = EclipseUiUtils.fillAll(); + gd.minimumHeight = 300; + userTableViewerCmp.setLayoutData(gd); + userTableViewerCmp.refresh(); + + // Controllers + userViewer = userTableViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new MyDoubleClickListener()); + userViewer + .addSelectionChangedListener(new MySelectionChangedListener()); + + parent.pack(); + return dialogArea; + } + + public User getSelected() { + if (selectedUser == null) + return null; + else + return selectedUser; + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(title); + } + + class MyDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + if (evt.getSelection().isEmpty()) + return; + + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + if (obj instanceof User) { + selectedUser = (User) obj; + okPressed(); + } + } + } + + class MySelectionChangedListener implements ISelectionChangedListener { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (event.getSelection().isEmpty()) { + selectedUser = null; + return; + } + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (obj instanceof Group) { + selectedUser = (Group) obj; + } + } + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 8467999509931900367L; + + private final String[] knownProps = { LdifName.uid.name(), + LdifName.cn.name(), LdifName.dn.name() }; + + private Button showSystemRoleBtn; + private Button showUserBtn; + + public MyUserTableViewer(Composite parent, int style) { + super(parent, style); + } + + protected void populateStaticFilters(Composite staticFilterCmp) { + staticFilterCmp.setLayout(new GridLayout()); + showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); + showSystemRoleBtn.setText("Show system roles "); + + showUserBtn = new Button(staticFilterCmp, SWT.CHECK); + showUserBtn.setText("Show users "); + + SelectionListener sl = new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + refresh(); + } + }; + + showSystemRoleBtn.addSelectionListener(sl); + showUserBtn.addSelectionListener(sl); + } + + @Override + protected List listFilteredElements(String filter) { + Role[] roles; + try { + StringBuilder builder = new StringBuilder(); + + StringBuilder filterBuilder = new StringBuilder(); + if (notNull(filter)) + for (String prop : knownProps) { + filterBuilder.append("("); + filterBuilder.append(prop); + filterBuilder.append("=*"); + filterBuilder.append(filter); + filterBuilder.append("*)"); + } + + String typeStr = "(" + LdifName.objectClass.name() + "=" + + LdifName.groupOfNames.name() + ")"; + if ((showUserBtn.getSelection())) + typeStr = "(|(" + LdifName.objectClass.name() + "=" + + LdifName.inetOrgPerson.name() + ")" + typeStr + + ")"; + + if (!showSystemRoleBtn.getSelection()) + typeStr = "(& " + typeStr + "(!(" + LdifName.dn.name() + + "=*" + UsersUtils.ROLES_BASEDN + ")))"; + + if (filterBuilder.length() > 1) { + builder.append("(&" + typeStr); + builder.append("(|"); + builder.append(filterBuilder.toString()); + builder.append("))"); + } else { + builder.append(typeStr); + } + roles = userAdmin.getRoles(builder.toString()); + } catch (InvalidSyntaxException e) { + throw new EclipseUiException("Unable to get roles with filter: " + + filter, e); + } + List users = new ArrayList(); + for (Role role : roles) + if (!users.contains(role)) + users.add((User) role); + return users; + } + } + + private boolean notNull(String string) { + if (string == null) + return false; + else + return !"".equals(string.trim()); + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserLP.java new file mode 100644 index 000000000..592af3cd5 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserLP.java @@ -0,0 +1,95 @@ +package org.argeo.cms.ui.workbench.useradmin; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; + +import org.argeo.cms.ui.workbench.internal.useradmin.UsersImages; +import org.argeo.cms.ui.workbench.internal.useradmin.UsersUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** Centralize label providers for the group table */ +class UserLP extends ColumnLabelProvider { + private static final long serialVersionUID = -4645930210988368571L; + + final static String COL_ICON = "colID.icon"; + final static String COL_DN = "colID.dn"; + final static String COL_DISPLAY_NAME = "colID.displayName"; + final static String COL_DOMAIN = "colID.domain"; + + final String currType; + + // private Font italic; + private Font bold; + + UserLP(String colId) { + this.currType = colId; + } + + @Override + public Font getFont(Object element) { + // Self as bold + try { + LdapName selfUserName = UsersUtils.getLdapName(); + String userName = ((User) element).getName(); + LdapName userLdapName = new LdapName(userName); + if (userLdapName.equals(selfUserName)) { + if (bold == null) + bold = JFaceResources.getFontRegistry() + .defaultFontDescriptor().setStyle(SWT.BOLD) + .createFont(Display.getCurrent()); + return bold; + } + } catch (InvalidNameException e) { + throw new EclipseUiException("cannot parse dn for " + element, e); + } + + // Disabled as Italic + // Node userProfile = (Node) elem; + // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) + // return italic; + + return null; + // return super.getFont(element); + } + + @Override + public Image getImage(Object element) { + if (COL_ICON.equals(currType)) { + User user = (User) element; + String dn = user.getName(); + if (dn.endsWith(UsersUtils.ROLES_BASEDN)) + return UsersImages.ICON_ROLE; + else if (user.getType() == Role.GROUP) + return UsersImages.ICON_GROUP; + else + return UsersImages.ICON_USER; + } else + return null; + } + + @Override + public String getText(Object element) { + User user = (User) element; + return getText(user); + + } + + public String getText(User user) { + if (COL_DN.equals(currType)) + return user.getName(); + else if (COL_DISPLAY_NAME.equals(currType)) + return UsersUtils.getCommonName(user); + else if (COL_DOMAIN.equals(currType)) + return UsersUtils.getDomainName(user); + else + return ""; + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java new file mode 100644 index 000000000..c5a39c152 --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.useradmin; + +import java.util.TreeSet; + +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** Information about the currently logged in user */ +public class UserProfile extends ViewPart { + public static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".userProfile"; + + private TableViewer viewer; + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new GridLayout(2, false)); + + // Authentication authentication = CurrentUser.getAuthentication(); + // EclipseUiUtils.createGridLL(parent, "Name", authentication + // .getPrincipal().toString()); + EclipseUiUtils.createGridLL(parent, "User ID", + CurrentUser.getUsername()); + + // roles table + Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + table.setLinesVisible(false); + table.setHeaderVisible(false); + viewer = new TableViewer(table); + viewer.setContentProvider(new RolesContentProvider()); + viewer.setLabelProvider(new LabelProvider()); + getViewSite().setSelectionProvider(viewer); + viewer.setInput(getViewSite()); + } + + @Override + public void setFocus() { + viewer.getTable(); + } + + private class RolesContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -4576917440167866233L; + + public Object[] getElements(Object inputElement) { + return new TreeSet(CurrentUser.roles()).toArray(); + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + +} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java new file mode 100644 index 000000000..4845f317d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.services.IServiceLocator; + +/** + * Centralises useful and generic methods when dealing with commands in an + * Eclipse Workbench context + */ +public class CommandUtils { + + /** + * Commodities the refresh of a single command with no parameter in a + * Menu.aboutToShow method to simplify further development + * + * Note: that this method should be called with a false show command flag to + * remove a contribution that have been previously contributed + * + * @param menuManager + * @param locator + * @param cmdId + * @param label + * @param icon + * @param showCommand + */ + public static void refreshCommand(IMenuManager menuManager, + IServiceLocator locator, String cmdId, String label, + ImageDescriptor icon, boolean showCommand) { + refreshParameterizedCommand(menuManager, locator, cmdId, label, icon, + showCommand, null); + } + + /** + * Commodities the refresh the contribution of a command with a map of + * parameters in a context menu + * + * The command ID is used has contribution item ID + * + * @param menuManager + * @param locator + * @param cmdId + * @param label + * @param iconPath + * @param showCommand + */ + public static void refreshParameterizedCommand(IMenuManager menuManager, + IServiceLocator locator, String cmdId, String label, + ImageDescriptor icon, boolean showCommand, + Map params) { + refreshParameterizedCommand(menuManager, locator, cmdId, cmdId, label, + icon, showCommand, params); + } + + /** + * Commodities the refresh the contribution of a command with a map of + * parameters in a context menu + * + * @param menuManager + * @param locator + * @param contributionId + * @param commandId + * @param label + * @param icon + * @param showCommand + * @param params + */ + public static void refreshParameterizedCommand(IMenuManager menuManager, + IServiceLocator locator, String contributionId, String commandId, + String label, ImageDescriptor icon, boolean showCommand, + Map params) { + IContributionItem ici = menuManager.find(contributionId); + if (ici != null) + menuManager.remove(ici); + if (showCommand) { + CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter( + locator, null, commandId, SWT.PUSH); + + // Set Params + contributionItemParameter.label = label; + contributionItemParameter.icon = icon; + + if (params != null) + contributionItemParameter.parameters = params; + + CommandContributionItem cci = new CommandContributionItem( + contributionItemParameter); + cci.setId(contributionId); + menuManager.add(cci); + } + } + + /** Helper to call a command without parameter easily */ + public static void callCommand(String commandID) { + callCommand(commandID, null); + } + + /** Helper to call a command with a single parameter easily */ + public static void callCommand(String commandID, String parameterID, + String parameterValue) { + Map params = new HashMap(); + params.put(parameterID, parameterValue); + callCommand(commandID, params); + } + + /** + * Helper to call a command with a map of parameters easily + * + * @param paramMap + * a map that links various command IDs with corresponding String + * values. + */ + public static void callCommand(String commandID, + Map paramMap) { + try { + IWorkbench iw = WorkbenchUiPlugin.getDefault().getWorkbench(); + IHandlerService handlerService = (IHandlerService) iw + .getService(IHandlerService.class); + ICommandService cmdService = (ICommandService) iw + .getActiveWorkbenchWindow().getService( + ICommandService.class); + Command cmd = cmdService.getCommand(commandID); + + ArrayList parameters = null; + ParameterizedCommand pc; + + if (paramMap != null) { + // Set parameters of the command to launch : + parameters = new ArrayList(); + Parameterization parameterization; + + for (String id : paramMap.keySet()) { + parameterization = new Parameterization( + cmd.getParameter(id), paramMap.get(id)); + parameters.add(parameterization); + } + pc = new ParameterizedCommand(cmd, + parameters.toArray(new Parameterization[parameters + .size()])); + } else + pc = new ParameterizedCommand(cmd, null); + + // execute the command + handlerService.executeCommand(pc, null); + } catch (Exception e) { + throw new EclipseUiException("Unexpected error while" + + " calling the command " + commandID, e); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java new file mode 100644 index 000000000..c232f03fd --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java @@ -0,0 +1,49 @@ +package org.argeo.cms.ui.workbench.util; + +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.security.auth.Subject; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.Job; + +/** + * Propagate authentication to an eclipse job. Typically to execute a privileged + * action outside the UI thread + */ +public abstract class PrivilegedJob extends Job { + private final Subject subject; + + public PrivilegedJob(String jobName) { + this(jobName, AccessController.getContext()); + } + + public PrivilegedJob(String jobName, + AccessControlContext accessControlContext) { + super(jobName); + subject = Subject.getSubject(accessControlContext); + + // Must be called *before* the job is scheduled, + // it is required for the progress window to appear + setUser(true); + } + + @Override + protected IStatus run(final IProgressMonitor progressMonitor) { + PrivilegedAction privilegedAction = new PrivilegedAction() { + public IStatus run() { + return doRun(progressMonitor); + } + }; + return Subject.doAs(subject, privilegedAction); + } + + /** + * Implement here what should be executed with default context + * authentication + */ + protected abstract IStatus doRun(IProgressMonitor progressMonitor); +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java new file mode 100644 index 000000000..4bf0d342d --- /dev/null +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.ui.workbench.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.argeo.cms.auth.CurrentUser; +import org.eclipse.ui.AbstractSourceProvider; + +/** + * Provides the roles of the current user as a variable to be used for activity + * binding + */ +public class RolesSourceProvider extends AbstractSourceProvider { + public final static String ROLES_VARIABLE = "roles"; + private final static String[] PROVIDED_SOURCE_NAMES = new String[] { ROLES_VARIABLE }; + + public Map> getCurrentState() { + Map> stateMap = new HashMap>(); + stateMap.put(ROLES_VARIABLE, CurrentUser.roles()); + return stateMap; + } + + public String[] getProvidedSourceNames() { + return PROVIDED_SOURCE_NAMES; + } + + public void updateRoles() { + fireSourceChanged(0, getCurrentState()); + } + + public void dispose() { + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/CommandUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/CommandUtils.java deleted file mode 100644 index 1cb369eb1..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/CommandUtils.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.core.commands.Command; -import org.eclipse.core.commands.Parameterization; -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.SWT; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.commands.ICommandService; -import org.eclipse.ui.handlers.IHandlerService; -import org.eclipse.ui.menus.CommandContributionItem; -import org.eclipse.ui.menus.CommandContributionItemParameter; -import org.eclipse.ui.services.IServiceLocator; - -/** - * Centralises useful and generic methods when dealing with commands in an - * Eclipse Workbench context - */ -public class CommandUtils { - - /** - * Commodities the refresh of a single command with no parameter in a - * Menu.aboutToShow method to simplify further development - * - * Note: that this method should be called with a false show command flag to - * remove a contribution that have been previously contributed - * - * @param menuManager - * @param locator - * @param cmdId - * @param label - * @param icon - * @param showCommand - */ - public static void refreshCommand(IMenuManager menuManager, - IServiceLocator locator, String cmdId, String label, - ImageDescriptor icon, boolean showCommand) { - refreshParameterizedCommand(menuManager, locator, cmdId, label, icon, - showCommand, null); - } - - /** - * Commodities the refresh the contribution of a command with a map of - * parameters in a context menu - * - * The command ID is used has contribution item ID - * - * @param menuManager - * @param locator - * @param cmdId - * @param label - * @param iconPath - * @param showCommand - */ - public static void refreshParameterizedCommand(IMenuManager menuManager, - IServiceLocator locator, String cmdId, String label, - ImageDescriptor icon, boolean showCommand, - Map params) { - refreshParameterizedCommand(menuManager, locator, cmdId, cmdId, label, - icon, showCommand, params); - } - - /** - * Commodities the refresh the contribution of a command with a map of - * parameters in a context menu - * - * @param menuManager - * @param locator - * @param contributionId - * @param commandId - * @param label - * @param icon - * @param showCommand - * @param params - */ - public static void refreshParameterizedCommand(IMenuManager menuManager, - IServiceLocator locator, String contributionId, String commandId, - String label, ImageDescriptor icon, boolean showCommand, - Map params) { - IContributionItem ici = menuManager.find(contributionId); - if (ici != null) - menuManager.remove(ici); - if (showCommand) { - CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter( - locator, null, commandId, SWT.PUSH); - - // Set Params - contributionItemParameter.label = label; - contributionItemParameter.icon = icon; - - if (params != null) - contributionItemParameter.parameters = params; - - CommandContributionItem cci = new CommandContributionItem( - contributionItemParameter); - cci.setId(contributionId); - menuManager.add(cci); - } - } - - /** Helper to call a command without parameter easily */ - public static void callCommand(String commandID) { - callCommand(commandID, null); - } - - /** Helper to call a command with a single parameter easily */ - public static void callCommand(String commandID, String parameterID, - String parameterValue) { - Map params = new HashMap(); - params.put(parameterID, parameterValue); - callCommand(commandID, params); - } - - /** - * Helper to call a command with a map of parameters easily - * - * @param paramMap - * a map that links various command IDs with corresponding String - * values. - */ - public static void callCommand(String commandID, - Map paramMap) { - try { - IWorkbench iw = SecurityUiPlugin.getDefault().getWorkbench(); - IHandlerService handlerService = (IHandlerService) iw - .getService(IHandlerService.class); - ICommandService cmdService = (ICommandService) iw - .getActiveWorkbenchWindow().getService( - ICommandService.class); - Command cmd = cmdService.getCommand(commandID); - - ArrayList parameters = null; - ParameterizedCommand pc; - - if (paramMap != null) { - // Set parameters of the command to launch : - parameters = new ArrayList(); - Parameterization parameterization; - - for (String id : paramMap.keySet()) { - parameterization = new Parameterization( - cmd.getParameter(id), paramMap.get(id)); - parameters.add(parameterization); - } - pc = new ParameterizedCommand(cmd, - parameters.toArray(new Parameterization[parameters - .size()])); - } else - pc = new ParameterizedCommand(cmd, null); - - // execute the command - handlerService.executeCommand(pc, null); - } catch (Exception e) { - throw new EclipseUiException("Unexpected error while" - + " calling the command " + commandID, e); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/ErrorFeedback.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/ErrorFeedback.java deleted file mode 100644 index e7e9c3bd8..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/ErrorFeedback.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench; - -import org.eclipse.swt.widgets.Shell; - -/** @deprecated Use {@link org.argeo.eclipse.ui.dialogs.ErrorFeedback} instead. */ -@Deprecated -public class ErrorFeedback extends org.argeo.eclipse.ui.dialogs.ErrorFeedback { - private static final long serialVersionUID = 5346084648745909554L; - - public ErrorFeedback(Shell parentShell, String message, Throwable e) { - super(parentShell, message, e); - } - -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/WorkbenchConstants.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/WorkbenchConstants.java deleted file mode 100644 index f08b040bf..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/WorkbenchConstants.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench; - -/** Constants used across the application. */ -public interface WorkbenchConstants { - /* - * MISCEALLENEOUS - */ - public final static String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm"; - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/WorkbenchUiPlugin.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/WorkbenchUiPlugin.java deleted file mode 100644 index e45c9a050..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/WorkbenchUiPlugin.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench; - -public class WorkbenchUiPlugin { -} - -// /** -// * The activator class controls the plug-in life cycle -// */ -// public class SecurityUiPlugin extends AbstractUIPlugin implements -// ILogListener { -// private final static Log log = LogFactory.getLog(SecurityUiPlugin.class); -// private ResourceBundle messages; -// -// // The plug-in ID -// public static final String ID = "org.argeo.eclipse.ui.workbench"; //$NON-NLS-1$ -// -// // The shared instance -// private static SecurityUiPlugin plugin; -// -// /** -// * The constructor -// */ -// public SecurityUiPlugin() { -// } -// -// public void start(BundleContext context) throws Exception { -// super.start(context); -// plugin = this; -// messages = ResourceBundle.getBundle(ID + ".messages"); -// Platform.addLogListener(this); -// if (log.isTraceEnabled()) -// log.trace("Eclipse logging now directed to standard logging"); -// } -// -// public void stop(BundleContext context) throws Exception { -// try { -// Platform.removeLogListener(this); -// if (log.isTraceEnabled()) -// log.trace("Eclipse logging not directed anymore to standard logging"); -// plugin = null; -// } finally { -// super.stop(context); -// } -// } -// -// /** -// * Returns the shared instance -// * -// * @return the shared instance -// */ -// public static SecurityUiPlugin getDefault() { -// return plugin; -// } -// -// public static ImageDescriptor getImageDescriptor(String path) { -// 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 this UiPlugin is not started (for JUnit tests, by instance) -// */ -// public static ResourceBundle getMessagesBundle() { -// if (getDefault() != null) -// // To avoid NPE -// return getDefault().messages; -// else -// return null; -// } -// -// public void logging(IStatus status, String plugin) { -// Log pluginLog = LogFactory.getLog(plugin); -// Integer severity = status.getSeverity(); -// if (severity == IStatus.ERROR) -// pluginLog.error(status.getMessage(), status.getException()); -// else if (severity == IStatus.WARNING) -// pluginLog.warn(status.getMessage(), status.getException()); -// else if (severity == IStatus.INFO) -// pluginLog.info(status.getMessage(), status.getException()); -// else if (severity == IStatus.CANCEL) -// if (pluginLog.isDebugEnabled()) -// pluginLog.debug(status.getMessage(), status.getException()); -// } -// } diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddFolderNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddFolderNode.java deleted file mode 100644 index 534d15f00..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddFolderNode.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.dialogs.SingleValue; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -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, only on {@link SingleJcrNodeElem} and - * {@link WorkspaceElem} TreeObject types. - * - * This handler assumes that a selection provider is available and picks only - * first selected item. It is UI's job to enable the command only when the - * selection contains one and only one element. Thus no parameter is passed - * through the command. - */ -public class AddFolderNode extends AbstractHandler { - - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".addFolderNode"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - - JcrBrowserView view = (JcrBrowserView) HandlerUtil - .getActiveWorkbenchWindow(event).getActivePage() - .findView(HandlerUtil.getActivePartId(event)); - - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - TreeParent treeParentNode = null; - Node jcrParentNode = null; - - if (obj instanceof SingleJcrNodeElem) { - treeParentNode = (TreeParent) obj; - jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode(); - } else if (obj instanceof WorkspaceElem) { - treeParentNode = (TreeParent) obj; - jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode(); - } else - return null; - - String folderName = SingleValue.ask("Folder name", - "Enter folder name"); - if (folderName != null) { - try { - jcrParentNode.addNode(folderName, NodeType.NT_FOLDER); - jcrParentNode.getSession().save(); - view.nodeAdded(treeParentNode); - } catch (RepositoryException e) { - ErrorFeedback.show("Cannot create folder " + folderName - + " under " + treeParentNode, e); - } - } - } else { - ErrorFeedback.show(SecurityUiPlugin - .getMessage("errorUnvalidNtFolderNodeType")); - } - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java deleted file mode 100644 index 6deb673c8..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.AddPrivilegeWizard; -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.jface.wizard.WizardDialog; -import org.eclipse.ui.handlers.HandlerUtil; -import org.osgi.service.useradmin.UserAdmin; - -/** Open a dialog to add privileges on the selected node to a chosen group */ -public class AddPrivileges extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".addPrivileges"; - - /* DEPENDENCY INJECTION */ - private UserAdmin userAdmin; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - TreeParent treeParentNode = null; - Node jcrParentNode = null; - - if (obj instanceof SingleJcrNodeElem) { - treeParentNode = (TreeParent) obj; - jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode(); - } else if (obj instanceof WorkspaceElem) { - treeParentNode = (TreeParent) obj; - jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode(); - } else - return null; - - try { - String targetPath = jcrParentNode.getPath(); - AddPrivilegeWizard wizard = new AddPrivilegeWizard( - jcrParentNode.getSession(), targetPath, userAdmin); - WizardDialog dialog = new WizardDialog( - HandlerUtil.getActiveShell(event), wizard); - dialog.open(); - return null; - } catch (RepositoryException re) { - throw new EclipseUiException("Unable to retrieve " - + "path or JCR session to add privilege on " - + jcrParentNode, re); - } - } else { - ErrorFeedback.show("Cannot add privileges"); - } - return null; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdmin(UserAdmin userAdmin) { - this.userAdmin = userAdmin; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddRemoteRepository.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddRemoteRepository.java deleted file mode 100644 index 06b6fe4a8..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddRemoteRepository.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.net.URI; -import java.util.Hashtable; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.SimpleCredentials; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.CommandUtils; -import org.argeo.eclipse.ui.workbench.WorkbenchConstants; -import org.argeo.jcr.JcrUtils; -import org.argeo.node.ArgeoNames; -import org.argeo.node.ArgeoTypes; -import org.argeo.node.NodeConstants; -import org.argeo.node.NodeUtils; -import org.argeo.node.security.Keyring; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -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.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * Connect to a remote repository and, if successful publish it as an OSGi - * service. - */ -public class AddRemoteRepository extends AbstractHandler implements - WorkbenchConstants, ArgeoNames { - - private RepositoryFactory repositoryFactory; - private Repository nodeRepository; - private Keyring keyring; - - public Object execute(ExecutionEvent event) throws ExecutionException { - RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog( - Display.getDefault().getActiveShell()); - if (dlg.open() == Dialog.OK) { - CommandUtils.callCommand(Refresh.ID); - } - return null; - } - - public void setRepositoryFactory(RepositoryFactory repositoryFactory) { - this.repositoryFactory = repositoryFactory; - } - - public void setKeyring(Keyring keyring) { - this.keyring = keyring; - } - - public void setNodeRepository(Repository nodeRepository) { - this.nodeRepository = nodeRepository; - } - - class RemoteRepositoryLoginDialog extends TitleAreaDialog { - private static final long serialVersionUID = 2234006887750103399L; - private Text name; - private Text uri; - private Text username; - private Text password; - private Button saveInKeyring; - - public RemoteRepositoryLoginDialog(Shell parentShell) { - super(parentShell); - } - - protected Point getInitialSize() { - return new Point(600, 400); - } - - protected Control createDialogArea(Composite parent) { - Composite dialogarea = (Composite) super.createDialogArea(parent); - dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - true)); - Composite composite = new Composite(dialogarea, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); - setMessage("Login to remote repository", IMessageProvider.NONE); - name = createLT(composite, "Name", "remoteRepository"); - uri = createLT(composite, "URI", - "http://localhost:7070/data/jcr/node"); - username = createLT(composite, "User", ""); - password = createLP(composite, "Password"); - - saveInKeyring = createLC(composite, "Remember password", false); - parent.pack(); - return composite; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - super.createButtonsForButtonBar(parent); - Button test = createButton(parent, 2, "Test", false); - test.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -1829962269440419560L; - - public void widgetSelected(SelectionEvent arg0) { - testConnection(); - } - }); - } - - void testConnection() { - Session session = null; - try { - URI checkedUri = new URI(uri.getText()); - String checkedUriStr = checkedUri.toString(); - - Hashtable params = new Hashtable(); - params.put(NodeConstants.JCR_REPOSITORY_URI, checkedUriStr); - Repository repository = repositoryFactory.getRepository(params); - if (username.getText().trim().equals("")) {// anonymous - session = repository.login(); - } else { - // FIXME use getTextChars() when upgrading to 3.7 - // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412 - char[] pwd = password.getText().toCharArray(); - SimpleCredentials sc = new SimpleCredentials( - username.getText(), pwd); - session = repository.login(sc, "main"); - MessageDialog.openInformation(getParentShell(), "Success", - "Connection to '" + uri.getText() + "' successful"); - } - } catch (Exception e) { - ErrorFeedback.show( - "Connection test failed for " + uri.getText(), e); - } finally { - JcrUtils.logoutQuietly(session); - } - } - - @Override - protected void okPressed() { - Session nodeSession = null; - try { - nodeSession = nodeRepository.login(); - Node home = NodeUtils.getUserHome(nodeSession); - - Node remote = home.hasNode(ARGEO_REMOTE) ? home - .getNode(ARGEO_REMOTE) : home.addNode(ARGEO_REMOTE); - if (remote.hasNode(name.getText())) - throw new EclipseUiException( - "There is already a remote repository named " - + name.getText()); - Node remoteRepository = remote.addNode(name.getText(), - ArgeoTypes.ARGEO_REMOTE_REPOSITORY); - remoteRepository.setProperty(ARGEO_URI, uri.getText()); - remoteRepository.setProperty(ARGEO_USER_ID, username.getText()); - nodeSession.save(); - if (saveInKeyring.getSelection()) { - String pwdPath = remoteRepository.getPath() + '/' - + ARGEO_PASSWORD; - keyring.set(pwdPath, password.getText().toCharArray()); - } - nodeSession.save(); - MessageDialog.openInformation( - getParentShell(), - "Repository Added", - "Remote repository '" + username.getText() + "@" - + uri.getText() + "' added"); - - super.okPressed(); - } catch (Exception e) { - ErrorFeedback.show("Cannot add remote repository", e); - } finally { - JcrUtils.logoutQuietly(nodeSession); - } - } - - /** Creates label and text. */ - protected Text createLT(Composite parent, String label, String initial) { - new Label(parent, SWT.NONE).setText(label); - Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - text.setText(initial); - return text; - } - - /** Creates label and check. */ - protected Button createLC(Composite parent, String label, - Boolean initial) { - new Label(parent, SWT.NONE).setText(label); - Button check = new Button(parent, SWT.CHECK); - check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - check.setSelection(initial); - return check; - } - - protected Text createLP(Composite parent, String label) { - new Label(parent, SWT.NONE).setText(label); - Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER - | SWT.PASSWORD); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - return text; - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java deleted file mode 100644 index a4183bd11..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.util.Arrays; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.dialogs.SingleValue; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoryElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -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; - -/** Create a new JCR workspace */ -public class CreateWorkspace extends AbstractHandler { - - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".addFolderNode"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - - JcrBrowserView view = (JcrBrowserView) HandlerUtil - .getActiveWorkbenchWindow(event).getActivePage() - .findView(HandlerUtil.getActivePartId(event)); - - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - if (!(obj instanceof RepositoryElem)) - return null; - - RepositoryElem repositoryNode = (RepositoryElem) obj; - String workspaceName = SingleValue.ask("Workspace name", - "Enter workspace name"); - if (workspaceName != null) { - if (Arrays.asList(repositoryNode.getAccessibleWorkspaceNames()) - .contains(workspaceName)) { - ErrorFeedback.show("Workspace " + workspaceName - + " already exists."); - } else { - repositoryNode.createWorkspace(workspaceName); - view.nodeAdded(repositoryNode); - } - } - } else { - ErrorFeedback.show("Cannot create workspace"); - } - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java deleted file mode 100644 index 76530484a..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.util.Iterator; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -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.ui.handlers.HandlerUtil; - -/** - * Delete 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. - * - * This handler is still 'hard linked' to a GenericJcrBrowser view to enable - * correct tree refresh when a node is added. This must be corrected in future - * versions. - */ -public class DeleteNodes extends AbstractHandler { - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - if (selection == null || !(selection instanceof IStructuredSelection)) - return null; - - JcrBrowserView view = (JcrBrowserView) HandlerUtil - .getActiveWorkbenchWindow(event).getActivePage() - .findView(HandlerUtil.getActivePartId(event)); - - // confirmation - StringBuffer buf = new StringBuffer(""); - Iterator lst = ((IStructuredSelection) selection).iterator(); - while (lst.hasNext()) { - SingleJcrNodeElem sjn = ((SingleJcrNodeElem) lst.next()); - buf.append(sjn.getName()).append(' '); - } - Boolean ok = MessageDialog.openConfirm( - HandlerUtil.getActiveShell(event), "Confirm deletion", - "Do you want to delete " + buf + "?"); - - // operation - if (ok) { - Iterator it = ((IStructuredSelection) selection).iterator(); - Object obj = null; - SingleJcrNodeElem ancestor = null; - WorkspaceElem rootAncestor = null; - try { - while (it.hasNext()) { - obj = it.next(); - if (obj instanceof SingleJcrNodeElem) { - // Cache objects - SingleJcrNodeElem sjn = (SingleJcrNodeElem) 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 WorkspaceElem) - rootAncestor = (WorkspaceElem) tp; - else - ancestor = getOlder(ancestor, (SingleJcrNodeElem) 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 SingleJcrNodeElem getOlder(SingleJcrNodeElem A, SingleJcrNodeElem 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 EclipseUiException("Cannot find ancestor", re); - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DoNothing.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DoNothing.java deleted file mode 100644 index 1a1808ae3..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DoNothing.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.argeo.eclipse.ui.workbench.commands; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; - -/** Utilitary command to enable sub menus in various toolbars. Does nothing */ -public class DoNothing extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".doNothing"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DumpNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DumpNode.java deleted file mode 100644 index 0c7dda062..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DumpNode.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.CommandUtils; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.jcr.JcrUtils; -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; - -/** - * Canonically call JCR {@link Session#exportSystemView()} on the first element - * returned by {@link HandlerUtil#getActiveWorkbenchWindow()} - * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}, - * with both skipBinary & noRecurse boolean flags set to false. - * - * Resulting stream is saved in a tmp file and opened via the {@link OpenFile} - * single-sourced command. - */ -public class DumpNode extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".dumpNode"; - - private final static DateFormat df = new SimpleDateFormat( - "yyyy-MM-dd_HH-mm"); - - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - if (selection == null || !(selection instanceof IStructuredSelection)) - return null; - - Iterator lst = ((IStructuredSelection) selection).iterator(); - if (lst.hasNext()) { - Object element = lst.next(); - if (element instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; - Node node = sjn.getNode(); - - // TODO add a dialog to configure the export and ask for - // confirmation - // Boolean ok = MessageDialog.openConfirm( - // HandlerUtil.getActiveShell(event), "Confirm deletion", - // "Do you want to delete " + buf + "?"); - - File tmpFile; - FileOutputStream fos; - try { - tmpFile = File.createTempFile("JcrExport", ".xml"); - tmpFile.deleteOnExit(); - fos = new FileOutputStream(tmpFile); - String dateVal = df.format(new GregorianCalendar() - .getTime()); - node.getSession().exportSystemView(node.getPath(), fos, - true, false); - openGeneratedFile(tmpFile.getAbsolutePath(), "Dump-" - + JcrUtils.replaceInvalidChars(node.getName()) - + "-" + dateVal + ".xml"); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unable to perform SystemExport on " + node, e); - } catch (IOException e) { - throw new EclipseUiException("Unable to SystemExport " - + node, e); - } - } - } - return null; - } - - private synchronized void openGeneratedFile(String path, String fileName) { - Map params = new HashMap(); - params.put(OpenFile.PARAM_FILE_NAME, fileName); - params.put(OpenFile.PARAM_FILE_URI, "file://" + path); - CommandUtils.callCommand(OpenFile.ID, params); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/EditNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/EditNode.java deleted file mode 100644 index d97074714..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/EditNode.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.Property; -import javax.jcr.nodetype.NodeType; - -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.NodeEditorInput; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Generic command to open a path in an editor. */ -public class EditNode extends AbstractHandler { - public final static String EDITOR_PARAM = "editor"; - - private String defaultEditorId; - - private Map nodeTypeToEditor = new HashMap(); - - public Object execute(ExecutionEvent event) throws ExecutionException { - String path = event.getParameter(Property.JCR_PATH); - - String type = event.getParameter(NodeType.NT_NODE_TYPE); - if (type == null) - type = NodeType.NT_UNSTRUCTURED; - - String editorId = event.getParameter(NodeType.NT_NODE_TYPE); - if (editorId == null) - editorId = nodeTypeToEditor.containsKey(type) ? nodeTypeToEditor - .get(type) : defaultEditorId; - - NodeEditorInput nei = new NodeEditorInput(path); - - try { - HandlerUtil.getActiveWorkbenchWindow(event).getActivePage() - .openEditor(nei, editorId); - } catch (PartInitException e) { - ErrorFeedback.show("Cannot open " + editorId + " with " + path - + " of type " + type, e); - } - // TODO Auto-generated method stub - return null; - } - - public void setDefaultEditorId(String defaultEditorId) { - this.defaultEditorId = defaultEditorId; - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java deleted file mode 100644 index 85fa3cb38..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.jcr.Node; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.jcr.JcrUtils; -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; - -/** Compute an approximative size for the selected node(s) */ -public class GetNodeSize extends AbstractHandler { - // private final static Log log = LogFactory.getLog(GetNodeSize.class); - - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".getNodeSize"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - - long size = 0; - - Iterator it = ((IStructuredSelection) selection).iterator(); - - // TODO enhance this: as the size method is recursive, we keep track - // of nodes for which we already have computed size so that we don't - // count them twice. In a first approximation, we assume that the - // structure selection keep the nodes ordered. - List importedPathes = new ArrayList(); - try { - nodesIt: while (it.hasNext()) { - Object obj = it.next(); - String curPath; - Node node; - if (obj instanceof SingleJcrNodeElem) { - node = ((SingleJcrNodeElem) obj).getNode(); - curPath = node.getSession().getWorkspace().getName(); - curPath += "/" + node.getPath(); - } else if (obj instanceof WorkspaceElem) { - node = ((WorkspaceElem) obj).getRootNode(); - curPath = node.getSession().getWorkspace().getName(); - } else - // non valid object type - continue nodesIt; - - Iterator itPath = importedPathes.iterator(); - while (itPath.hasNext()) { - String refPath = itPath.next(); - if (curPath.startsWith(refPath)) - // Already done : skip node - continue nodesIt; - } - size += JcrUtils.getNodeApproxSize(node); - importedPathes.add(curPath); - } - } catch (Exception e) { - ErrorFeedback.show("Cannot Get size of selected node ", e); - } - - 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; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/ImportFileSystem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/ImportFileSystem.java deleted file mode 100644 index 54e847a72..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/ImportFileSystem.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import javax.jcr.Node; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.ImportFileSystemWizard; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -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.jface.wizard.WizardDialog; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Import a local file system directory tree. */ -public class ImportFileSystem extends AbstractHandler { - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - JcrBrowserView view = (JcrBrowserView) HandlerUtil - .getActiveWorkbenchWindow(event).getActivePage() - .findView(HandlerUtil.getActivePartId(event)); - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - try { - Node folder = null; - if (obj instanceof SingleJcrNodeElem) { - folder = ((SingleJcrNodeElem) obj).getNode(); - } else if (obj instanceof WorkspaceElem) { - folder = ((WorkspaceElem) obj).getRootNode(); - } else { - ErrorFeedback.show(SecurityUiPlugin - .getMessage("warningInvalidNodeToImport")); - } - if (folder != null) { - ImportFileSystemWizard wizard = new ImportFileSystemWizard( - folder); - WizardDialog dialog = new WizardDialog( - HandlerUtil.getActiveShell(event), wizard); - dialog.open(); - view.nodeAdded((TreeParent) obj); - } - } catch (Exception e) { - ErrorFeedback.show("Cannot import files to " + obj, e); - } - } - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/NodeConfigurableDump.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/NodeConfigurableDump.java deleted file mode 100644 index 5e77bef6d..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/NodeConfigurableDump.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.jcr.JcrUtils; -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.jface.window.Window; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -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.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * First draft of a wizard that enable configurable recursive dump of the - * current selected Node (Only one at a time). Enable among other to export - * children Nodes and to choose to export binaries or not. It is useful to - * retrieve business data from live systems to prepare migration or test locally - */ -public class NodeConfigurableDump extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".nodeConfigurableDump"; - - private final static DateFormat df = new SimpleDateFormat( - "yyyy-MM-dd_HH-mm"); - - public final static int EXPORT_NODE = 0; - public final static int EXPORT_CHILDREN = 1; - public final static int EXPORT_GRAND_CHILDREN = 2; - - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - if (selection == null || !(selection instanceof IStructuredSelection)) - return null; - - Iterator lst = ((IStructuredSelection) selection).iterator(); - if (lst.hasNext()) { - Object element = lst.next(); - if (element instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; - Node node = sjn.getNode(); - - ConfigureDumpWizard wizard = new ConfigureDumpWizard( - HandlerUtil.getActiveShell(event), - "Import Resource CSV"); - WizardDialog dialog = new WizardDialog( - HandlerUtil.getActiveShell(event), wizard); - int result = dialog.open(); - - if (result == Window.OK) { - - String dateVal = df.format(new GregorianCalendar() - .getTime()); - try { - - Path tmpDirPath = Files.createTempDirectory(dateVal - + "-NodeDump-"); - List toExport = retrieveToExportNodes(node, - wizard.currExportType); - - for (Node currNode : toExport) { - FileOutputStream fos; - String fileName = wizard.prefix - + JcrUtils.replaceInvalidChars(currNode - .getName()) + "_" + dateVal - + ".xml"; - File currFile = new File(tmpDirPath.toString() - + "/" + fileName); - currFile.createNewFile(); - fos = new FileOutputStream(currFile); - node.getSession().exportSystemView( - currNode.getPath(), fos, - !wizard.includeBinaries, false); - fos.flush(); - fos.close(); - } - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unable to perform SystemExport on " + node, e); - } catch (IOException e) { - throw new EclipseUiException("Unable to SystemExport " - + node, e); - } - } - } - } - return null; - } - - private List retrieveToExportNodes(Node node, int currExportType) - throws RepositoryException { - List nodes = new ArrayList(); - switch (currExportType) { - case EXPORT_NODE: - nodes.add(node); - return nodes; - case EXPORT_CHILDREN: - return JcrUtils.nodeIteratorToList(node.getNodes()); - case EXPORT_GRAND_CHILDREN: - NodeIterator nit = node.getNodes(); - while (nit.hasNext()) - nodes.addAll(JcrUtils.nodeIteratorToList(nit.nextNode() - .getNodes())); - return nodes; - - default: - return nodes; - } - } - - // private synchronized void openGeneratedFile(String path, String fileName) - // { - // Map params = new HashMap(); - // params.put(OpenFile.PARAM_FILE_NAME, fileName); - // params.put(OpenFile.PARAM_FILE_URI, "file://" + path); - // CommandUtils.callCommand("org.argeo.security.ui.specific.openFile", - // params); - // } - - private class ConfigureDumpWizard extends Wizard { - - // parameters - protected String prefix; - protected int currExportType = EXPORT_NODE; - protected boolean includeBinaries = false; - - // UI Objects - private BasicPage page; - private Text prefixTxt; - private Button includeBinaryBtn; - private Button b1, b2, b3; - - public ConfigureDumpWizard(Shell parentShell, String title) { - setWindowTitle(title); - } - - @Override - public void addPages() { - try { - page = new BasicPage("Main page"); - addPage(page); - } catch (Exception e) { - throw new EclipseUiException("Cannot add page to wizard", e); - } - } - - @Override - public boolean performFinish() { - prefix = prefixTxt.getText(); - if (b1.getSelection()) - currExportType = EXPORT_NODE; - else if (b2.getSelection()) - currExportType = EXPORT_CHILDREN; - else if (b3.getSelection()) - currExportType = EXPORT_GRAND_CHILDREN; - includeBinaries = includeBinaryBtn.getSelection(); - return true; - } - - @Override - public boolean performCancel() { - return true; - } - - @Override - public boolean canFinish() { - String errorMsg = "No prefix defined."; - if ("".equals(prefixTxt.getText().trim())) { - page.setErrorMessage(errorMsg); - return false; - } else { - page.setErrorMessage(null); - return true; - } - } - - protected class BasicPage extends WizardPage { - private static final long serialVersionUID = 1L; - - public BasicPage(String pageName) { - super(pageName); - setTitle("Configure dump before launching"); - setMessage("Define the parameters of the dump to launch"); - } - - public void createControl(Composite parent) { - parent.setLayout(noSpaceGridLayout()); - - // Main Layout - Composite mainCmp = new Composite(parent, SWT.NONE); - mainCmp.setLayout(new GridLayout(2, false)); - mainCmp.setLayoutData(fillAll()); - - // The path - createBoldLabel(mainCmp, "Prefix"); - prefixTxt = new Text(mainCmp, SWT.SINGLE | SWT.BORDER); - prefixTxt.setLayoutData(fillAll()); - prefixTxt.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = 1L; - - @Override - public void modifyText(ModifyEvent event) { - if (prefixTxt.getText() != null) - getWizard().getContainer().updateButtons(); - } - }); - - new Label(mainCmp, SWT.SEPARATOR | SWT.HORIZONTAL) - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false, 2, 1)); - - // Which node to export - Label typeLbl = new Label(mainCmp, SWT.RIGHT); - typeLbl.setText(" Type"); - typeLbl.setFont(EclipseUiUtils.getBoldFont(mainCmp)); - typeLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, - false, 1, 3)); - - b1 = new Button(mainCmp, SWT.RADIO); - b1.setText("Export this node"); - b1.setSelection(true); - b2 = new Button(mainCmp, SWT.RADIO); - b2.setText("Export children nodes"); - b3 = new Button(mainCmp, SWT.RADIO); - b3.setText("Export grand-children nodes"); - - new Label(mainCmp, SWT.SEPARATOR | SWT.HORIZONTAL) - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false, 2, 1)); - - createBoldLabel(mainCmp, "Files and images"); - includeBinaryBtn = new Button(mainCmp, SWT.CHECK); - includeBinaryBtn.setText("Include binaries"); - - prefixTxt.setFocus(); - setControl(mainCmp); - } - } - } - - private Label createBoldLabel(Composite parent, String value) { - Label label = new Label(parent, SWT.RIGHT); - label.setText(" " + value); - label.setFont(EclipseUiUtils.getBoldFont(parent)); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - return label; - } - - // TODO rather use EclipseUiUtils methods - private GridLayout noSpaceGridLayout() { - return noSpaceGridLayout(new GridLayout()); - } - - private GridLayout noSpaceGridLayout(GridLayout layout) { - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - layout.marginWidth = 0; - layout.marginHeight = 0; - return layout; - } - - private GridData fillAll() { - return new GridData(SWT.FILL, SWT.FILL, true, true); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java deleted file mode 100644 index eb7deb02d..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import javax.jcr.Node; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.JcrQueryEditorInput; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.NodeEditorInput; -import org.argeo.eclipse.ui.workbench.jcr.DefaultNodeEditor; -import org.argeo.eclipse.ui.workbench.jcr.GenericJcrQueryEditor; -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.PartInitException; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Open a {@link Node} editor of a specific type given the node path */ -public class OpenEditor extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".openEditor"; - - public final static String PARAM_PATH = "param.jcrNodePath"; - public final static String PARAM_EDITOR_ID = "param.editorId"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - String editorId = event.getParameter(PARAM_EDITOR_ID); - try { - IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow( - event).getActivePage(); - if (DefaultNodeEditor.ID.equals(editorId)) { - String path = event.getParameter(PARAM_PATH); - NodeEditorInput nei = new NodeEditorInput(path); - activePage.openEditor(nei, DefaultNodeEditor.ID); - } else if (GenericJcrQueryEditor.ID.equals(editorId)) { - JcrQueryEditorInput editorInput = new JcrQueryEditorInput( - GenericJcrQueryEditor.ID, null); - activePage.openEditor(editorInput, editorId); - } - } catch (PartInitException e) { - throw new EclipseUiException( - "Cannot open editor of ID " + editorId, e); - } - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenFile.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenFile.java deleted file mode 100644 index c6129db3d..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenFile.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.specific.OpenFileService; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; - -/** - * RWT specific command handler to open a file retrieved from the server. It - * forwards the request to the correct service after encoding file name and path - * in the request URI. - * - *

- * The parameter "URI" is used to determine the correct file service, the path - * and the file name. An optional file name can be precized to present a - * different file name as the one used to retrieve it to the end user. - *

- * - *

- * Various instances of this handler with different command ID might coexist in - * order to provide context specific download service. - *

- * - *

- * The instance specific service is called by its ID and must have been - * externally created - *

- */ -public class OpenFile extends AbstractHandler { - // private final static Log log = LogFactory.getLog(OpenFile.class); - - /* DEPENDENCY INJECTION */ - private String openFileServiceId; - - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".openFile"; - public final static String PARAM_FILE_NAME = OpenFileService.PARAM_FILE_NAME; - public final static String PARAM_FILE_URI = OpenFileService.PARAM_FILE_URI; // "param.fileURI"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - String fileName = event.getParameter(PARAM_FILE_NAME); - String fileUri = event.getParameter(PARAM_FILE_URI); - // Sanity check - if (fileUri == null || "".equals(fileUri.trim()) - || openFileServiceId == null - || "".equals(openFileServiceId.trim())) - return null; - - org.argeo.eclipse.ui.specific.OpenFile openFileClient = new org.argeo.eclipse.ui.specific.OpenFile(); - openFileClient.execute(openFileServiceId, fileUri, fileName); - - return null; - } - - /* DEPENDENCY INJECTION */ - public void setOpenFileServiceId(String openFileServiceId) { - this.openFileServiceId = openFileServiceId; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/Refresh.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/Refresh.java deleted file mode 100644 index b08736270..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/Refresh.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.util.Iterator; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.workbench.internal.jcr.JcrBrowserUtils; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -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; - -/** - * Force the selected objects of the active view to be refreshed doing the - * following: - *
    - *
  1. The model objects are recomputed
  2. - *
  3. the view is refreshed
  4. - *
- */ -public class Refresh extends AbstractHandler { - - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".refresh"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - JcrBrowserView view = (JcrBrowserView) SecurityUiPlugin.getDefault() - .getWorkbench().getActiveWorkbenchWindow().getActivePage() - .getActivePart();// - - ISelection selection = SecurityUiPlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getActivePage().getSelection(); - - if (selection != null && selection instanceof IStructuredSelection - && !selection.isEmpty()) { - Iterator it = ((IStructuredSelection) selection).iterator(); - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof TreeParent) { - TreeParent tp = (TreeParent) obj; - JcrBrowserUtils.forceRefreshIfNeeded(tp); - view.refresh(obj); - } - } - } else if (view instanceof JcrBrowserView) - ((JcrBrowserView) view).refresh(null); // force full refresh - - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RemovePrivileges.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RemovePrivileges.java deleted file mode 100644 index 9a6841d31..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RemovePrivileges.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.security.Principal; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.security.AccessControlEntry; -import javax.jcr.security.AccessControlList; -import javax.jcr.security.AccessControlManager; -import javax.jcr.security.Privilege; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrImages; -import org.argeo.jcr.JcrUtils; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -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.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Open a dialog to remove privileges from the selected node */ -public class RemovePrivileges extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".removePrivileges"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - TreeParent uiNode = null; - Node jcrNode = null; - - if (obj instanceof SingleJcrNodeElem) { - uiNode = (TreeParent) obj; - jcrNode = ((SingleJcrNodeElem) uiNode).getNode(); - } else if (obj instanceof WorkspaceElem) { - uiNode = (TreeParent) obj; - jcrNode = ((WorkspaceElem) uiNode).getRootNode(); - } else - return null; - - try { - String targetPath = jcrNode.getPath(); - Dialog dialog = new RemovePrivDialog( - HandlerUtil.getActiveShell(event), - jcrNode.getSession(), targetPath); - dialog.open(); - return null; - } catch (RepositoryException re) { - throw new EclipseUiException("Unable to retrieve " - + "path or JCR session to add privilege on " + jcrNode, - re); - } - } else { - ErrorFeedback.show("Cannot add privileges"); - } - return null; - } - - private class RemovePrivDialog extends TitleAreaDialog { - private static final long serialVersionUID = 280139710002698692L; - - private Composite body; - - private final String path; - private final Session session; - - public RemovePrivDialog(Shell parentShell, Session session, String path) { - super(parentShell); - this.session = session; - this.path = path; - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText("Remove privileges"); - } - - protected Control createDialogArea(Composite parent) { - Composite dialogarea = (Composite) super.createDialogArea(parent); - dialogarea.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, - true)); - body = new Composite(dialogarea, SWT.NONE); - body.setLayoutData(EclipseUiUtils.fillAll()); - refreshContent(); - parent.pack(); - return body; - } - - private void refreshContent() { - EclipseUiUtils.clear(body); - try { - AccessControlManager acm = session.getAccessControlManager(); - AccessControlList acl = JcrUtils - .getAccessControlList(acm, path); - if (acl == null || acl.getAccessControlEntries().length <= 0) - setMessage("No privilege are defined on this node", - IMessageProvider.INFORMATION); - else { - body.setLayout(new GridLayout(3, false)); - for (AccessControlEntry ace : acl.getAccessControlEntries()) { - addOnePrivRow(body, ace); - } - setMessage("Remove some of the defined privileges", - IMessageProvider.INFORMATION); - } - } catch (RepositoryException e) { - throw new EclipseUiException("Unable to list privileges on " - + path, e); - } - body.layout(true, true); - } - - private void addOnePrivRow(Composite parent, AccessControlEntry ace) { - Principal currentPrincipal = ace.getPrincipal(); - final String currPrincipalName = currentPrincipal.getName(); - new Label(parent, SWT.WRAP).setText(currPrincipalName); - new Label(parent, SWT.WRAP).setText(privAsString(ace - .getPrivileges())); - final Button rmBtn = new Button(parent, SWT.FLAT); - rmBtn.setImage(JcrImages.REMOVE); - - rmBtn.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 7566938841363890730L; - - @Override - public void widgetSelected(SelectionEvent e) { - - if (MessageDialog.openConfirm(rmBtn.getShell(), - "Confirm deletion", - "Are you sure you want to remove this privilege?")) { - try { - session.save(); - JcrUtils.clearAccessControList(session, path, - currPrincipalName); - session.save(); - refreshContent(); - } catch (RepositoryException re) { - throw new EclipseUiException("Unable to " - + "remove privilege for " - + currPrincipalName + " on " + path, re); - } - } - - super.widgetSelected(e); - } - }); - - } - - private String privAsString(Privilege[] currentPrivileges) { - - StringBuilder builder = new StringBuilder(); - builder.append("[ "); - for (Privilege priv : currentPrivileges) { - builder.append(priv.getName()).append(", "); - } - if (builder.length() > 3) - return builder.substring(0, builder.length() - 2) + " ]"; - else - return "[]"; - - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RemoveRemoteRepository.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RemoveRemoteRepository.java deleted file mode 100644 index 8f6f58f41..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RemoveRemoteRepository.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RemoteRepositoryElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -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; - -/** Remove a registered remote repository */ -public class RemoveRemoteRepository extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getSelection(); - - JcrBrowserView view = (JcrBrowserView) HandlerUtil - .getActiveWorkbenchWindow(event).getActivePage() - .findView(HandlerUtil.getActivePartId(event)); - - if (selection != null && !selection.isEmpty() - && selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - - if (obj instanceof RemoteRepositoryElem) { - ((RemoteRepositoryElem) obj).remove(); - view.refresh(null); - } - } - return null; - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RenameNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RenameNode.java deleted file mode 100644 index 6710a0abc..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/RenameNode.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import java.util.Iterator; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.SingleValue; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -import org.argeo.jcr.JcrUtils; -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.IWorkbenchPage; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Canonically call JCR {@link Session#move(String, String)} on the first - * element returned by {@link HandlerUtil#getActiveWorkbenchWindow()} - * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}. - * The user must then fill a new name in and confirm - */ -public class RenameNode extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".renameNode"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage(); - - ISelection selection = iwp.getSelection(); - if (selection == null || !(selection instanceof IStructuredSelection)) - return null; - - Iterator lst = ((IStructuredSelection) selection).iterator(); - if (lst.hasNext()) { - Object element = lst.next(); - if (element instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; - Node node = sjn.getNode(); - Session session = null; - String newName = null; - String oldPath = null; - try { - newName = SingleValue.ask("New node name", - "Please provide a new name for [" + node.getName() - + "]"); - // TODO sanity check and user feedback - newName = JcrUtils.replaceInvalidChars(newName); - oldPath = node.getPath(); - session = node.getSession(); - session.move(oldPath, JcrUtils.parentPath(oldPath) + "/" - + newName); - session.save(); - - // Manually refresh the browser view. Must be enhanced - if (iwp.getActivePart() instanceof JcrBrowserView) - ((JcrBrowserView) iwp.getActivePart()).refresh(sjn); - } catch (RepositoryException e) { - throw new EclipseUiException("Unable to rename " + node - + " to " + newName, e); - } - } - } - return null; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java deleted file mode 100644 index 4d2ca6fdc..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.commands; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.workbench.jcr.JcrBrowserView; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.Command; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.commands.State; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.commands.ICommandService; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Change isSorted state of the DataExplorer Browser */ -public class SortChildNodes extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".sortChildNodes"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - JcrBrowserView view = (JcrBrowserView) HandlerUtil - .getActiveWorkbenchWindow(event).getActivePage() - .findView(JcrBrowserView.ID); - - ICommandService service = (ICommandService) PlatformUI.getWorkbench() - .getService(ICommandService.class); - Command command = service.getCommand(ID); - State state = command.getState(ID + ".toggleState"); - - boolean wasSorted = (Boolean) state.getValue(); - view.setSortChildNodes(!wasSorted); - state.setValue(!wasSorted); - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/FullVersioningTreeContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/FullVersioningTreeContentProvider.java deleted file mode 100644 index 7e4e2918a..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/FullVersioningTreeContentProvider.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; -import javax.jcr.version.Version; -import javax.jcr.version.VersionHistory; -import javax.jcr.version.VersionIterator; -import javax.jcr.version.VersionManager; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Display some version information of a JCR full versionable node in a tree - * like structure - */ -public class FullVersioningTreeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = 8691772509491211112L; - - /** - * Sends back the first level of the Tree. input element must be a single - * node object - */ - public Object[] getElements(Object inputElement) { - try { - Node rootNode = (Node) inputElement; - String curPath = rootNode.getPath(); - VersionManager vm = rootNode.getSession().getWorkspace() - .getVersionManager(); - - VersionHistory vh = vm.getVersionHistory(curPath); - List result = new ArrayList(); - VersionIterator vi = vh.getAllLinearVersions(); - - while (vi.hasNext()) { - result.add(vi.nextVersion()); - } - return result.toArray(); - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while getting version elements", re); - } - } - - public Object[] getChildren(Object parentElement) { - try { - if (parentElement instanceof Version) { - List tmp = new ArrayList(); - tmp.add(((Version) parentElement).getFrozenNode()); - return tmp.toArray(); - } - } catch (RepositoryException re) { - throw new EclipseUiException("Unexpected error while getting child " - + "node for version element", re); - } - return null; - } - - public Object getParent(Object element) { - try { - // this will not work in a simpleVersionning environment, parent is - // not a node. - if (element instanceof Node - && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) { - Node node = (Node) element; - return node.getParent(); - } else - return null; - } catch (RepositoryException e) { - return null; - } - } - - public boolean hasChildren(Object element) { - try { - if (element instanceof Version) - return true; - else if (element instanceof Node) - return ((Node) element).hasNodes(); - else - return false; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot check children of " + element, e); - } - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/GenericNodeDoubleClickListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/GenericNodeDoubleClickListener.java deleted file mode 100644 index 03721af39..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/GenericNodeDoubleClickListener.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoryElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.GenericNodeEditorInput; -import org.argeo.eclipse.ui.workbench.jcr.DefaultNodeEditor; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.ui.PartInitException; - -/** Centralizes the management of double click on a NodeTreeViewer */ -public class GenericNodeDoubleClickListener implements IDoubleClickListener { - // private final static Log log = LogFactory - // .getLog(GenericNodeDoubleClickListener.class); - - private TreeViewer nodeViewer; - - // private JcrFileProvider jfp; - // private FileHandler fileHandler; - - public GenericNodeDoubleClickListener(TreeViewer nodeViewer) { - this.nodeViewer = nodeViewer; - // jfp = new JcrFileProvider(); - // Commented out. see https://www.argeo.org/bugzilla/show_bug.cgi?id=188 - // fileHandler = null; - // fileHandler = new FileHandler(jfp); - } - - public void doubleClick(DoubleClickEvent event) { - if (event.getSelection() == null || event.getSelection().isEmpty()) - return; - Object obj = ((IStructuredSelection) event.getSelection()) - .getFirstElement(); - if (obj instanceof RepositoryElem) { - RepositoryElem rpNode = (RepositoryElem) obj; - if (!rpNode.isConnected()) { - rpNode.login(); - nodeViewer.refresh(obj); - } - } else if (obj instanceof WorkspaceElem) { - WorkspaceElem wn = (WorkspaceElem) obj; - if (wn.isConnected()) - wn.logout(); - else - wn.login(); - nodeViewer.refresh(obj); - } else if (obj instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj; - Node node = sjn.getNode(); - try { - if (node.isNodeType(NodeType.NT_FILE)) { - // double click on a file node triggers its opening - // String name = node.getName(); - // String id = node.getIdentifier(); - - // TODO add integration of direct retrieval of the binary in - // a JCR repo. - // Map params = new HashMap(); - // params.put(OpenFile.PARAM_FILE_NAME, name); - // params.put(OpenFile.PARAM_FILE_URI, "jcr://" + id); - // CommandUtils - // .callCommand("org.argeo.security.ui.specific.openFile", - // params); - - // For the file provider to be able to browse the - // various - // repository. - // TODO : enhanced that. - // ITreeContentProvider itcp = (ITreeContentProvider) - // nodeViewer - // .getContentProvider(); - // jfp.setReferenceNode(node); - // if (fileHandler != null) - // fileHandler.openFile(name, id); - } - GenericNodeEditorInput gnei = new GenericNodeEditorInput(node); - SecurityUiPlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getActivePage() - .openEditor(gnei, DefaultNodeEditor.ID); - } catch (RepositoryException re) { - throw new EclipseUiException( - "Repository error while getting node info", re); - } catch (PartInitException pie) { - throw new EclipseUiException( - "Unexepected exception while opening node editor", pie); - } - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/JcrBrowserUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/JcrBrowserUtils.java deleted file mode 100644 index 9e3e31878..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/JcrBrowserUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoriesElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoryElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; - -/** Centralizes useful methods to manage the JCR Browser */ -public class JcrBrowserUtils { - - /** Insure that the UI component is not stale, refresh if needed */ - public static void forceRefreshIfNeeded(TreeParent element) { - Node curNode = null; - - boolean doRefresh = false; - - try { - if (element instanceof SingleJcrNodeElem) { - curNode = ((SingleJcrNodeElem) element).getNode(); - } else if (element instanceof WorkspaceElem) { - curNode = ((WorkspaceElem) element).getRootNode(); - } - - if (curNode != null - && element.getChildren().length != curNode.getNodes() - .getSize()) - doRefresh = true; - else if (element instanceof RepositoryElem) { - RepositoryElem rn = (RepositoryElem) element; - if (rn.isConnected()) { - String[] wkpNames = rn.getAccessibleWorkspaceNames(); - if (element.getChildren().length != wkpNames.length) - doRefresh = true; - } - } else if (element instanceof RepositoriesElem) { - doRefresh = true; - // Always force refresh for RepositoriesElem : the condition - // below does not take remote repository into account and it is - // not trivial to do so. - - // RepositoriesElem rn = (RepositoriesElem) element; - // if (element.getChildren().length != - // rn.getRepositoryRegister() - // .getRepositories().size()) - // doRefresh = true; - } - if (doRefresh) { - element.clearChildren(); - element.getChildren(); - } - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while synchronising the UI with the JCR repository", - re); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/NodeContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/NodeContentProvider.java deleted file mode 100644 index be623871e..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/NodeContentProvider.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; - -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoriesElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.jcr.RepositoryRegister; -import org.argeo.node.NodeConstants; -import org.argeo.node.NodeUtils; -import org.argeo.node.security.Keyring; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Implementation of the {@code ITreeContentProvider} to display multiple - * repository environment in a tree like structure - */ -public class NodeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = -4083809398848374403L; - final private RepositoryRegister repositoryRegister; - final private RepositoryFactory repositoryFactory; - - // Current user session on the default workspace of the argeo Node - final private Session userSession; - final private Keyring keyring; - private boolean sortChildren; - - // Reference for cleaning - private SingleJcrNodeElem homeNode = null; - private RepositoriesElem repositoriesNode = null; - - // Utils - private TreeBrowserComparator itemComparator = new TreeBrowserComparator(); - - public NodeContentProvider(Session userSession, Keyring keyring, - RepositoryRegister repositoryRegister, - RepositoryFactory repositoryFactory, Boolean sortChildren) { - this.userSession = userSession; - this.keyring = keyring; - this.repositoryRegister = repositoryRegister; - this.repositoryFactory = repositoryFactory; - this.sortChildren = sortChildren; - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput == null)// dispose - return; - - if (userSession != null) { - Node userHome = NodeUtils.getUserHome(userSession); - if (userHome != null) { - // TODO : find a way to dynamically get alias for the node - if (homeNode != null) - homeNode.dispose(); - homeNode = new SingleJcrNodeElem(null, userHome, - userSession.getUserID(), NodeConstants.ALIAS_NODE); - } - } - if (repositoryRegister != null) { - if (repositoriesNode != null) - repositoriesNode.dispose(); - repositoriesNode = new RepositoriesElem("Repositories", - repositoryRegister, repositoryFactory, null, userSession, - keyring); - } - } - - /** - * Sends back the first level of the Tree. Independent from inputElement - * that can be null - */ - public Object[] getElements(Object inputElement) { - List objs = new ArrayList(); - if (homeNode != null) - objs.add(homeNode); - if (repositoriesNode != null) - objs.add(repositoriesNode); - return objs.toArray(); - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof TreeParent) { - if (sortChildren) { - Object[] tmpArr = ((TreeParent) parentElement).getChildren(); - if (tmpArr == null) - return new Object[0]; - TreeParent[] arr = new TreeParent[tmpArr.length]; - for (int i = 0; i < tmpArr.length; i++) - arr[i] = (TreeParent) tmpArr[i]; - Arrays.sort(arr, itemComparator); - return arr; - } else - return ((TreeParent) parentElement).getChildren(); - } else - return new Object[0]; - } - - /** - * Sets whether the content provider should order the children nodes or not. - * It is user duty to call a full refresh of the tree after changing this - * parameter. - */ - public void setSortChildren(boolean sortChildren) { - this.sortChildren = sortChildren; - } - - public Object getParent(Object element) { - if (element instanceof TreeParent) { - return ((TreeParent) element).getParent(); - } else - return null; - } - - public boolean hasChildren(Object element) { - if (element instanceof RepositoriesElem) { - RepositoryRegister rr = ((RepositoriesElem) element) - .getRepositoryRegister(); - return rr.getRepositories().size() > 0; - } else if (element instanceof TreeParent) { - TreeParent tp = (TreeParent) element; - return tp.hasChildren(); - } - return false; - } - - public void dispose() { - if (homeNode != null) - homeNode.dispose(); - if (repositoriesNode != null) { - // logs out open sessions - // see https://bugzilla.argeo.org/show_bug.cgi?id=23 - repositoriesNode.dispose(); - } - } - - /** - * Specific comparator for this view. See specification here: - * https://www.argeo.org/bugzilla/show_bug.cgi?id=139 - */ - private class TreeBrowserComparator implements Comparator { - - public int category(TreeParent element) { - if (element instanceof SingleJcrNodeElem) { - Node node = ((SingleJcrNodeElem) element).getNode(); - try { - if (node.isNodeType(NodeType.NT_FOLDER)) - return 5; - } catch (RepositoryException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - return 10; - } - - public int compare(TreeParent o1, TreeParent o2) { - int cat1 = category(o1); - int cat2 = category(o2); - - if (cat1 != cat2) { - return cat1 - cat2; - } - return o1.getName().compareTo(o2.getName()); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/NodeLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/NodeLabelProvider.java deleted file mode 100644 index 34f0398fc..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/NodeLabelProvider.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RemoteRepositoryElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoriesElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.RepositoryElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.workbench.jcr.JcrImages; -import org.argeo.node.ArgeoTypes; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.swt.graphics.Image; - -/** Provides reasonable defaults for know JCR types. */ -public class NodeLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = -3662051696443321843L; - - private final static Log log = LogFactory.getLog(NodeLabelProvider.class); - - public String getText(Object element) { - try { - if (element instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; - return getText(sjn.getNode()); - } else if (element instanceof Node) { - return getText((Node) element); - } else - return super.getText(element); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected JCR error while getting node name."); - } - } - - protected String getText(Node node) throws RepositoryException { - String label = node.getName(); - StringBuffer mixins = new StringBuffer(""); - for (NodeType type : node.getMixinNodeTypes()) - mixins.append(' ').append(type.getName()); - - return label + " [" + node.getPrimaryNodeType().getName() + mixins - + "]"; - } - - @Override - public Image getImage(Object element) { - if (element instanceof RemoteRepositoryElem) { - if (((RemoteRepositoryElem) element).isConnected()) - return JcrImages.REMOTE_CONNECTED; - else - return JcrImages.REMOTE_DISCONNECTED; - } else if (element instanceof RepositoryElem) { - if (((RepositoryElem) element).isConnected()) - return JcrImages.REPOSITORY_CONNECTED; - else - return JcrImages.REPOSITORY_DISCONNECTED; - } else if (element instanceof WorkspaceElem) { - if (((WorkspaceElem) element).isConnected()) - return JcrImages.WORKSPACE_CONNECTED; - else - return JcrImages.WORKSPACE_DISCONNECTED; - } else if (element instanceof RepositoriesElem) { - return JcrImages.REPOSITORIES; - } else if (element instanceof SingleJcrNodeElem) { - Node nodeElem = ((SingleJcrNodeElem) element).getNode(); - return getImage(nodeElem); - - // if (element instanceof Node) { - // return getImage((Node) element); - // } else if (element instanceof WrappedNode) { - // return getImage(((WrappedNode) element).getNode()); - // } else if (element instanceof NodesWrapper) { - // return getImage(((NodesWrapper) element).getNode()); - // } - } - // try { - // return super.getImage(); - // } catch (RepositoryException e) { - // return null; - // } - return super.getImage(element); - } - - protected Image getImage(Node node) { - try { - if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)) - return JcrImages.FILE; - else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER)) - return JcrImages.FOLDER; - else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_RESOURCE)) - return JcrImages.BINARY; - else if (node.isNodeType(ArgeoTypes.ARGEO_USER_HOME)) - return JcrImages.HOME; - else - return JcrImages.NODE; - } catch (RepositoryException e) { - log.warn("Error while retrieving type for " + node - + " in order to display corresponding image"); - e.printStackTrace(); - return null; - } - - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/PropertiesContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/PropertiesContentProvider.java deleted file mode 100644 index d0b0e394c..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/PropertiesContentProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import java.util.Set; -import java.util.TreeSet; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.Viewer; - -public class PropertiesContentProvider implements IStructuredContentProvider { - private static final long serialVersionUID = 5227554668841613078L; - private JcrItemsComparator itemComparator = new JcrItemsComparator(); - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public Object[] getElements(Object inputElement) { - try { - if (inputElement instanceof Node) { - Set props = new TreeSet(itemComparator); - PropertyIterator pit = ((Node) inputElement).getProperties(); - while (pit.hasNext()) - props.add(pit.nextProperty()); - return props.toArray(); - } - return new Object[] {}; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot get element for " + inputElement, - e); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/PropertyLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/PropertyLabelProvider.java deleted file mode 100644 index 34e91f4ca..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/PropertyLabelProvider.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; - -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; -import javax.jcr.Value; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.WorkbenchConstants; -import org.argeo.jcr.JcrUtils; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ViewerCell; - -/** Default basic label provider for a given JCR Node's properties */ -public class PropertyLabelProvider extends ColumnLabelProvider implements - WorkbenchConstants { - private static final long serialVersionUID = -5405794508731390147L; - - // To be able to change column order easily - public static final int COLUMN_PROPERTY = 0; - public static final int COLUMN_VALUE = 1; - public static final int COLUMN_ATTRIBUTES = 2; - - // Utils - protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT); - - public void update(ViewerCell cell) { - Object element = cell.getElement(); - cell.setText(getColumnText(element, cell.getColumnIndex())); - } - - public String getColumnText(Object element, int columnIndex) { - try { - if (element instanceof Property) { - Property prop = (Property) element; - if (prop.isMultiple()) { - switch (columnIndex) { - case COLUMN_PROPERTY: - return prop.getName(); - case COLUMN_VALUE: - // Corresponding values are listed on children - return ""; - case COLUMN_ATTRIBUTES: - return JcrUtils.getPropertyDefinitionAsString(prop); - } - } else { - switch (columnIndex) { - case COLUMN_PROPERTY: - return prop.getName(); - case COLUMN_VALUE: - return formatValueAsString(prop.getValue()); - case COLUMN_ATTRIBUTES: - return JcrUtils.getPropertyDefinitionAsString(prop); - } - } - } else if (element instanceof Value) { - Value val = (Value) element; - - switch (columnIndex) { - case COLUMN_PROPERTY: - // Nothing to show - return ""; - case COLUMN_VALUE: - return formatValueAsString(val); - case COLUMN_ATTRIBUTES: - // Corresponding attributes are listed on the parent - return ""; - } - } - - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexepected error while getting property values", re); - } - return null; - } - - private String formatValueAsString(Value value) { - // TODO enhance this method - try { - String strValue; - - if (value.getType() == PropertyType.BINARY) - strValue = ""; - else if (value.getType() == PropertyType.DATE) - strValue = timeFormatter.format(value.getDate().getTime()); - else - strValue = value.getString(); - return strValue; - } catch (RepositoryException e) { - throw new EclipseUiException("unexpected error while formatting value", - e); - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/SingleNodeAsTreeContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/SingleNodeAsTreeContentProvider.java deleted file mode 100644 index 7050b7b89..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/SingleNodeAsTreeContentProvider.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Implementation of the {@code ITreeContentProvider} in order to display a - * single JCR node and its children in a tree like structure - */ -public class SingleNodeAsTreeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = -2128326504754297297L; - // private Node rootNode; - private JcrItemsComparator itemComparator = new JcrItemsComparator(); - - /** - * Sends back the first level of the Tree. input element must be a single - * node object - */ - public Object[] getElements(Object inputElement) { - try { - Node rootNode = (Node) inputElement; - List result = new ArrayList(); - NodeIterator ni = rootNode.getNodes(); - while (ni.hasNext()) { - result.add(ni.nextNode()); - } - - return result.toArray(); - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while getting child nodes for children editor page ", - re); - } - } - - public Object[] getChildren(Object parentElement) { - return childrenNodes((Node) parentElement); - } - - public Object getParent(Object element) { - try { - Node node = (Node) element; - if (!node.getPath().equals("/")) - return node.getParent(); - else - return null; - } catch (RepositoryException e) { - return null; - } - } - - public boolean hasChildren(Object element) { - try { - return ((Node) element).hasNodes(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot check children of " + element, e); - } - } - - public void dispose() { - } - - 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 EclipseUiException("Cannot list children of " + parentNode, e); - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/VersionLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/VersionLabelProvider.java deleted file mode 100644 index e6672f2ce..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/VersionLabelProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.version.Version; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.viewers.ColumnLabelProvider; - -/** - * Simple wrapping of the ColumnLabelProvider class to provide text display in - * order to build a tree for version. The getText() method does not assume that - * {@link Version} extends {@link Node} class to respect JCR 2.0 specification - * - */ -public class VersionLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = 5270739851193688238L; - - public String getText(Object element) { - try { - if (element instanceof Version) { - Version version = (Version) element; - return version.getName(); - } else if (element instanceof Node) { - return ((Node) element).getName(); - } - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while getting element name", re); - } - return super.getText(element); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/MaintainedRepositoryElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/MaintainedRepositoryElem.java deleted file mode 100644 index 92cd0b1b5..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/MaintainedRepositoryElem.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.argeo.eclipse.ui.workbench.internal.jcr.model; - -import javax.jcr.Repository; - -import org.argeo.eclipse.ui.TreeParent; - -/** Wrap a MaintainedRepository */ -public class MaintainedRepositoryElem extends RepositoryElem { - - public MaintainedRepositoryElem(String alias, Repository repository, TreeParent parent) { - super(alias, repository, parent); - // if (!(repository instanceof MaintainedRepository)) { - // throw new ArgeoException("Repository " + alias - // + " is not amiantained repository"); - // } - } - - // protected MaintainedRepository getMaintainedRepository() { - // return (MaintainedRepository) getRepository(); - // } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RemoteRepositoryElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RemoteRepositoryElem.java deleted file mode 100644 index edaf2396f..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RemoteRepositoryElem.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.model; - -import java.util.Arrays; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.SimpleCredentials; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.node.ArgeoNames; -import org.argeo.node.NodeUtils; -import org.argeo.node.security.Keyring; - -/** Root of a remote repository */ -public class RemoteRepositoryElem extends RepositoryElem { - private final Keyring keyring; - /** - * A session of the logged in user on the default workspace of the node - * repository. - */ - private final Session userSession; - private final String remoteNodePath; - - private final RepositoryFactory repositoryFactory; - private final String uri; - - public RemoteRepositoryElem(String alias, - RepositoryFactory repositoryFactory, String uri, TreeParent parent, - Session userSession, Keyring keyring, String remoteNodePath) { - super(alias, null, parent); - this.repositoryFactory = repositoryFactory; - this.uri = uri; - this.keyring = keyring; - this.userSession = userSession; - this.remoteNodePath = remoteNodePath; - } - - @Override - protected Session repositoryLogin(String workspaceName) - throws RepositoryException { - Node remoteRepository = userSession.getNode(remoteNodePath); - String userID = remoteRepository.getProperty(ArgeoNames.ARGEO_USER_ID) - .getString(); - String pwdPath = remoteRepository.getPath() + '/' - + ArgeoNames.ARGEO_PASSWORD; - char[] password = keyring.getAsChars(pwdPath); - - try { - SimpleCredentials credentials = new SimpleCredentials(userID, - password); - return getRepository().login(credentials, workspaceName); - } finally { - Arrays.fill(password, 0, password.length, ' '); - } - } - - @Override - public Repository getRepository() { - if (repository == null) - repository = NodeUtils.getRepositoryByUri(repositoryFactory, - uri); - return super.getRepository(); - } - - public void remove() { - try { - Node remoteNode = userSession.getNode(remoteNodePath); - remoteNode.remove(); - remoteNode.getSession().save(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot remove " + remoteNodePath, e); - } - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RepositoriesElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RepositoriesElem.java deleted file mode 100644 index 294757acd..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RepositoriesElem.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.model; - -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.jcr.RepositoryRegister; -import org.argeo.node.ArgeoNames; -import org.argeo.node.NodeUtils; -import org.argeo.node.security.Keyring; - -/** - * UI Tree component that 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 RepositoriesElem extends TreeParent implements ArgeoNames { - private final RepositoryRegister repositoryRegister; - private final RepositoryFactory repositoryFactory; - - /** - * A session of the logged in user on the default workspace of the node - * repository. - */ - private final Session userSession; - private final Keyring keyring; - - public RepositoriesElem(String name, RepositoryRegister repositoryRegister, RepositoryFactory repositoryFactory, - TreeParent parent, Session userSession, Keyring keyring) { - super(name); - this.repositoryRegister = repositoryRegister; - this.repositoryFactory = repositoryFactory; - this.userSession = userSession; - this.keyring = keyring; - } - - /** - * Override normal behavior 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()) { - Repository repository = refRepos.get(name); - // if (repository instanceof MaintainedRepository) - // super.addChild(new MaintainedRepositoryElem(name, - // repository, this)); - // else - super.addChild(new RepositoryElem(name, repository, this)); - } - - // remote - if (keyring != null) { - try { - addRemoteRepositories(keyring); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot browse remote repositories", e); - } - } - return super.getChildren(); - } - } - - protected void addRemoteRepositories(Keyring jcrKeyring) throws RepositoryException { - Node userHome = NodeUtils.getUserHome(userSession); - if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) { - NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes(); - while (it.hasNext()) { - Node remoteNode = it.nextNode(); - String uri = remoteNode.getProperty(ARGEO_URI).getString(); - try { - RemoteRepositoryElem remoteRepositoryNode = new RemoteRepositoryElem(remoteNode.getName(), - repositoryFactory, uri, this, userSession, jcrKeyring, remoteNode.getPath()); - super.addChild(remoteRepositoryNode); - } catch (Exception e) { - ErrorFeedback.show("Cannot add remote repository " + remoteNode, e); - } - } - } - } - - 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 this object. */ - public RepositoryRegister getRepositoryRegister() { - return repositoryRegister; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RepositoryElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RepositoryElem.java deleted file mode 100644 index f3b73b042..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/RepositoryElem.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.model; - -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; - -/** - * UI Tree component that 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 RepositoryElem extends TreeParent { - private String alias; - protected Repository repository; - private Session defaultSession = null; - - /** Create a new repository with distinct name & alias */ - public RepositoryElem(String alias, Repository repository, TreeParent parent) { - super(alias); - this.repository = repository; - setParent(parent); - this.alias = alias; - } - - public void login() { - try { - defaultSession = repositoryLogin("main"); - String[] wkpNames = defaultSession.getWorkspace() - .getAccessibleWorkspaceNames(); - for (String wkpName : wkpNames) { - if (wkpName.equals(defaultSession.getWorkspace().getName())) - addChild(new WorkspaceElem(this, wkpName, defaultSession)); - else - addChild(new WorkspaceElem(this, wkpName)); - } - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot connect to repository " + alias, e); - } - } - - /** - * Actual call to the - * {@link Repository#login(javax.jcr.Credentials, String)} method. To be - * overridden. - */ - protected Session repositoryLogin(String workspaceName) - throws RepositoryException { - return repository.login(workspaceName); - } - - public String[] getAccessibleWorkspaceNames() { - try { - return defaultSession.getWorkspace().getAccessibleWorkspaceNames(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot retrieve workspace names", e); - } - } - - public void createWorkspace(String workspaceName) { - if (!isConnected()) - login(); - try { - defaultSession.getWorkspace().createWorkspace(workspaceName); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot create workspace", e); - } - } - - /** returns the {@link Repository} referenced by the current UI Node */ - public Repository getRepository() { - return repository; - } - - public String getAlias() { - return alias; - } - - public Boolean isConnected() { - if (defaultSession != null && defaultSession.isLive()) - return true; - else - return false; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/SingleJcrNodeElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/SingleJcrNodeElem.java deleted file mode 100644 index b69a4803a..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/SingleJcrNodeElem.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.model; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Workspace; - -import org.argeo.eclipse.ui.EclipseUiException; -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 WorkspaceElem}, a - * {@link SingleJcrNodeElem} or null if the node is "mounted" as the root of the UI - * tree. - */ - -public class SingleJcrNodeElem extends TreeParent { - - 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 SingleJcrNodeElem(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 SingleJcrNodeElem(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; - } - - protected String getRepositoryAlias() { - return alias; - } - - /** - * Override normal behavior 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 SingleJcrNodeElem(this, curNode, curNode.getName())); - } - return super.getChildren(); - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexcpected error while initializing children SingleJcrNode", - re); - } - } - } - - @Override - public boolean hasChildren() { - try { - if (node.getSession().isLive()) - return node.hasNodes(); - else - return false; - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while checking children node existence", - re); - } - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/WorkspaceElem.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/WorkspaceElem.java deleted file mode 100644 index e0e9a3e22..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/model/WorkspaceElem.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.model; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -// import javax.jcr.Workspace; -import javax.jcr.Workspace; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.TreeParent; -import org.argeo.jcr.JcrUtils; - -/** - * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also - * keeps a reference to its parent {@link RepositoryElem}, to be able to - * retrieve alias of the current used repository - */ -public class WorkspaceElem extends TreeParent { - private Session session = null; - - public WorkspaceElem(RepositoryElem parent, String name) { - this(parent, name, null); - } - - public WorkspaceElem(RepositoryElem parent, String name, Session session) { - super(name); - this.session = session; - setParent(parent); - } - - public synchronized Session getSession() { - return session; - } - - public synchronized Node getRootNode() { - try { - if (session != null) - return session.getRootNode(); - else - return null; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot get root node of workspace " - + getName(), e); - } - } - - public synchronized void login() { - try { - session = ((RepositoryElem) getParent()).repositoryLogin(getName()); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot connect to repository " - + getName(), e); - } - } - - public Boolean isConnected() { - if (session != null && session.isLive()) - return true; - else - return false; - } - - @Override - public synchronized void dispose() { - logout(); - super.dispose(); - } - - /** Logouts the session, does not nothing if there is no live session. */ - public synchronized void logout() { - clearChildren(); - JcrUtils.logoutQuietly(session); - session = null; - } - - @Override - public synchronized boolean hasChildren() { - try { - if (isConnected()) - return session.getRootNode().hasNodes(); - else - return false; - } catch (RepositoryException re) { - throw new EclipseUiException( - "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 SingleJcrNodeElem(this, node, node.getName())); - } - return super.getChildren(); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Cannot initialize WorkspaceNode UI object." - + getName(), e); - } - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java deleted file mode 100644 index 0633454ce..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -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.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.GenericTableComparator; -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.IDoubleClickListener; -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.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -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.swt.widgets.TableColumn; -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 { - private final static Log log = LogFactory - .getLog(AbstractJcrQueryEditor.class); - - protected String initialQuery; - protected String initialQueryType; - - /* DEPENDENCY INJECTION */ - private Session session; - - // Widgets - private TableViewer viewer; - private List tableViewerColumns = new ArrayList(); - private GenericTableComparator comparator; - - /** Override to layout a form enabling the end user to build his query */ - 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(4); - sashForm.setLayout(new FillLayout()); - - Composite top = new Composite(sashForm, SWT.NONE); - GridLayout gl = new GridLayout(1, false); - top.setLayout(gl); - - createQueryForm(top); - - Composite bottom = new Composite(sashForm, SWT.NONE); - bottom.setLayout(new GridLayout(1, false)); - sashForm.setWeights(getWeights()); - - viewer = new TableViewer(bottom); - viewer.getTable().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - viewer.getTable().setHeaderVisible(true); - viewer.setContentProvider(getQueryResultContentProvider()); - viewer.setInput(getEditorSite()); - - if (getComparator() != null) { - comparator = getComparator(); - viewer.setComparator(comparator); - } - if (getTableDoubleClickListener() != null) - viewer.addDoubleClickListener(getTableDoubleClickListener()); - - } - - protected void executeQuery(String statement) { - try { - if (log.isDebugEnabled()) - log.debug("Query : " + statement); - - QueryResult qr = session.getWorkspace().getQueryManager() - .createQuery(statement, initialQueryType).execute(); - - // remove previous columns - for (TableViewerColumn tvc : tableViewerColumns) - tvc.getColumn().dispose(); - - int i = 0; - for (final String columnName : qr.getColumnNames()) { - TableViewerColumn tvc = new TableViewerColumn(viewer, SWT.NONE); - configureColumn(columnName, tvc, i); - tvc.setLabelProvider(getLabelProvider(columnName)); - tableViewerColumns.add(tvc); - i++; - } - - // Must create a local list: QueryResults can only be read once. - try { - List rows = new ArrayList(); - RowIterator rit = qr.getRows(); - while (rit.hasNext()) { - rows.add(rit.nextRow()); - } - viewer.setInput(rows); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot read query result", e); - } - - } catch (RepositoryException e) { - ErrorDialog.openError(null, "Error", "Cannot execute JCR query: " - + statement, new Status(IStatus.ERROR, - "org.argeo.eclipse.ui.jcr", e.getMessage())); - } - } - - /** - * To be overidden to adapt size of form and result frames. - * - * @return - */ - protected int[] getWeights() { - return new int[] { 30, 70 }; - } - - /** - * To be overidden to implement a doubleclick Listener on one of the rows of - * the table. - * - * @return - */ - protected IDoubleClickListener getTableDoubleClickListener() { - return null; - } - - /** - * To be overiden in order to implement a specific - * QueryResultContentProvider - */ - protected IStructuredContentProvider getQueryResultContentProvider() { - return new QueryResultContentProvider(); - } - - /** - * Enable specific implementation for columns - */ - protected List getTableViewerColumns() { - return tableViewerColumns; - } - - /** - * Enable specific implementation for columns - */ - protected TableViewer getTableViewer() { - return viewer; - } - - /** - * To be overridden in order to configure column label providers . - */ - protected ColumnLabelProvider getLabelProvider(final String columnName) { - return new ColumnLabelProvider() { - private static final long serialVersionUID = -3539689333250152606L; - - public String getText(Object element) { - Row row = (Row) element; - try { - return row.getValue(columnName).getString(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot display row " + row, e); - } - } - - public Image getImage(Object element) { - return null; - } - }; - } - - /** - * To be overridden in order to configure the columns. - * - * @deprecated use {@link - * org.argeo.eclipse.ui.jcr.editors.AbstractJcrQueryEditor. - * configureColumn(String jcrColumnName, TableViewerColumn - * column, int columnIndex)} instead - */ - protected void configureColumn(String jcrColumnName, - TableViewerColumn column) { - column.getColumn().setWidth(50); - column.getColumn().setText(jcrColumnName); - } - - /** To be overridden in order to configure the columns. */ - protected void configureColumn(String jcrColumnName, - TableViewerColumn column, int columnIndex) { - column.getColumn().setWidth(50); - column.getColumn().setText(jcrColumnName); - } - - private class QueryResultContentProvider implements - IStructuredContentProvider { - private static final long serialVersionUID = -5421095459600554741L; - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public Object[] getElements(Object inputElement) { - - if (inputElement instanceof List) - return ((List) inputElement).toArray(); - - // Never reached might be deleted in future release - 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 EclipseUiException("Cannot read query result", e); - } - } - - } - - /** - * Might be used by children classes to sort columns. - * - * @param column - * @param index - * @return - */ - protected SelectionAdapter getSelectionAdapter(final TableColumn column, - final int index) { - - // A comparator must be define - if (comparator == null) - return null; - - SelectionAdapter selectionAdapter = new SelectionAdapter() { - private static final long serialVersionUID = 239829307927778349L; - - @Override - public void widgetSelected(SelectionEvent e) { - - try { - - comparator.setColumn(index); - int dir = viewer.getTable().getSortDirection(); - if (viewer.getTable().getSortColumn() == column) { - dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; - } else { - - dir = SWT.DOWN; - } - viewer.getTable().setSortDirection(dir); - viewer.getTable().setSortColumn(column); - viewer.refresh(); - } catch (Exception exc) { - exc.printStackTrace(); - } - } - }; - return selectionAdapter; - } - - /** - * To be overridden to enable sorting. - */ - protected GenericTableComparator getComparator() { - 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; - } - - /** Returns the injected current session */ - protected Session getSession() { - return session; - } - - /* DEPENDENCY INJECTION */ - public void setSession(Session session) { - this.session = session; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java deleted file mode 100644 index 1837ee7b7..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.security.Privilege; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.workbench.internal.users.UsersUtils; -import org.argeo.eclipse.ui.workbench.users.PickUpUserDialog; -import org.argeo.jcr.JcrUtils; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.window.Window; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Link; -import org.eclipse.swt.widgets.Text; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; - -/** Add JCR privileges to the chosen user group on a given node */ -public class AddPrivilegeWizard extends Wizard { - - // Context - private UserAdmin userAdmin; - private Session currentSession; - private String targetPath; - // Chosen parameters - private User chosenUser; - private String jcrPrivilege; - - // UI Object - private DefinePrivilegePage page; - - // TODO enable external definition of possible values and corresponding - // description - protected static final Map AUTH_TYPE_LABELS; - static { - Map tmpMap = new HashMap(); - tmpMap.put(Privilege.JCR_READ, "jcr:read"); - tmpMap.put(Privilege.JCR_WRITE, "jcr:write"); - tmpMap.put(Privilege.JCR_ALL, "jcr:all"); - AUTH_TYPE_LABELS = Collections.unmodifiableMap(tmpMap); - } - - protected static final Map AUTH_TYPE_DESC; - static { - Map tmpMap = new HashMap(); - tmpMap.put(Privilege.JCR_READ, - "The privilege to retrieve a node and get its properties and their values."); - tmpMap.put(Privilege.JCR_WRITE, "An aggregate privilege that " - + "contains: jcr:modifyProperties, jcr:addChildNodes, " - + "jcr:removeNode, jcr:removeChildNodes"); - tmpMap.put(Privilege.JCR_ALL, "An aggregate privilege that " - + "contains all JCR predefined privileges, " - + "plus all implementation-defined privileges. "); - AUTH_TYPE_DESC = Collections.unmodifiableMap(tmpMap); - } - - public AddPrivilegeWizard(Session currentSession, String path, - UserAdmin userAdmin) { - super(); - this.userAdmin = userAdmin; - this.currentSession = currentSession; - this.targetPath = path; - } - - @Override - public void addPages() { - try { - setWindowTitle("Add privilege on " + targetPath); - page = new DefinePrivilegePage(userAdmin, targetPath); - addPage(page); - } catch (Exception e) { - throw new EclipseUiException("Cannot add page to wizard ", e); - } - } - - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - try { - JcrUtils.addPrivilege(currentSession, targetPath, - chosenUser.getName(), jcrPrivilege); - } catch (RepositoryException re) { - throw new EclipseUiException("Cannot set " + jcrPrivilege + " for " - + chosenUser.getName() + " on " + targetPath, re); - } - return true; - } - - private class DefinePrivilegePage extends WizardPage implements - ModifyListener { - private static final long serialVersionUID = 8084431378762283920L; - - // Context - final private UserAdmin userAdmin; - - public DefinePrivilegePage(UserAdmin userAdmin, String path) { - super("Main"); - this.userAdmin = userAdmin; - setTitle("Define the privilege to apply to " + path); - setMessage("Please choose a user or a group and relevant JCR Privilege."); - } - - public void createControl(Composite parent) { - final Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(3, false)); - - // specify subject - createBoldLabel(composite, "User or group name"); - final Label groupNameLbl = new Label(composite, SWT.LEAD); - groupNameLbl.setLayoutData(EclipseUiUtils.fillWidth()); - - Link pickUpLk = new Link(composite, SWT.LEFT); - pickUpLk.setText(" Change "); - - createBoldLabel(composite, "User or group DN"); - final Text groupNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER); - groupNameTxt.setLayoutData(EclipseUiUtils.fillWidth(2)); - - pickUpLk.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 1L; - - @Override - public void widgetSelected(SelectionEvent e) { - PickUpUserDialog dialog = new PickUpUserDialog(getShell(), - "Choose a group or a user", userAdmin); - if (dialog.open() == Window.OK) { - chosenUser = dialog.getSelected(); - groupNameLbl.setText(UsersUtils - .getCommonName(chosenUser)); - groupNameTxt.setText(chosenUser.getName()); - } - } - }); - - groupNameTxt.addFocusListener(new FocusListener() { - private static final long serialVersionUID = 1965498600105667738L; - - @Override - public void focusLost(FocusEvent event) { - String dn = groupNameTxt.getText(); - if (EclipseUiUtils.isEmpty(dn)) - return; - - User newChosen = null; - try { - newChosen = (User) userAdmin.getRole(dn); - } catch (Exception e) { - boolean tryAgain = MessageDialog.openQuestion( - getShell(), "Unvalid DN", - "DN " + dn + " is not valid.\nError message: " - + e.getMessage() - + "\n\t\tDo you want to try again?"); - if (tryAgain) - groupNameTxt.setFocus(); - else - resetOnFail(); - } - - if (userAdmin.getRole(dn) == null) { - boolean tryAgain = MessageDialog.openQuestion( - getShell(), "Unexisting role", "User/group " - + dn + " does not exist. " - + "Do you want to try again?"); - if (tryAgain) - groupNameTxt.setFocus(); - else - resetOnFail(); - } else { - chosenUser = newChosen; - groupNameLbl.setText(UsersUtils - .getCommonName(chosenUser)); - } - } - - private void resetOnFail() { - String oldDn = chosenUser == null ? "" : chosenUser - .getName(); - groupNameTxt.setText(oldDn); - } - - @Override - public void focusGained(FocusEvent event) { - } - }); - - // JCR Privileges - createBoldLabel(composite, "Privilege type"); - Combo authorizationCmb = new Combo(composite, SWT.BORDER - | SWT.READ_ONLY | SWT.V_SCROLL); - authorizationCmb.setItems(AUTH_TYPE_LABELS.values().toArray( - new String[0])); - authorizationCmb.setLayoutData(EclipseUiUtils.fillWidth(2)); - createBoldLabel(composite, ""); // empty cell - final Label descLbl = new Label(composite, SWT.WRAP); - descLbl.setLayoutData(EclipseUiUtils.fillWidth(2)); - - authorizationCmb.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 1L; - - @Override - public void widgetSelected(SelectionEvent e) { - String chosenPrivStr = ((Combo) e.getSource()).getText(); - if (AUTH_TYPE_LABELS.containsValue(chosenPrivStr)) { - loop: for (String key : AUTH_TYPE_LABELS.keySet()) { - if (AUTH_TYPE_LABELS.get(key).equals(chosenPrivStr)) { - jcrPrivilege = key; - break loop; - } - } - } - - if (jcrPrivilege != null) { - descLbl.setText(AUTH_TYPE_DESC.get(jcrPrivilege)); - composite.layout(true, true); - } - } - }); - - // Compulsory - setControl(composite); - } - - public void modifyText(ModifyEvent event) { - String message = checkComplete(); - if (message != null) - setMessage(message, WizardPage.ERROR); - else { - setMessage("Complete", WizardPage.INFORMATION); - setPageComplete(true); - } - } - - /** @return error message or null if complete */ - protected String checkComplete() { - if (chosenUser == null) - return "Please choose a relevant group or user"; - else if (userAdmin.getRole(chosenUser.getName()) == null) - return "Please choose a relevant group or user"; - else if (jcrPrivilege == null) - return "Please choose a relevant JCR privilege"; - return null; - } - } - - private Label createBoldLabel(Composite parent, String value) { - Label label = new Label(parent, SWT.RIGHT); - label.setText(" " + value); - label.setFont(EclipseUiUtils.getBoldFont(parent)); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - return label; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ChildNodesPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ChildNodesPage.java deleted file mode 100644 index a115e6140..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ChildNodesPage.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import javax.jcr.Node; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.workbench.internal.jcr.NodeLabelProvider; -import org.argeo.eclipse.ui.workbench.internal.jcr.SingleNodeAsTreeContentProvider; -import org.argeo.eclipse.ui.workbench.jcr.DefaultNodeEditor; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * List all childs of the current node and brings some browsing capabilities - * accross the repository - */ -public class ChildNodesPage extends FormPage { - // private final static Log log = LogFactory.getLog(ChildNodesPage.class); - - // business objects - private Node currentNode; - - // this page UI components - private SingleNodeAsTreeContentProvider nodeContentProvider; - private TreeViewer nodesViewer; - - public ChildNodesPage(FormEditor editor, String title, Node currentNode) { - super(editor, "ChildNodesPage", title); - this.currentNode = currentNode; - } - - protected void createFormContent(IManagedForm managedForm) { - try { - ScrolledForm form = managedForm.getForm(); - form.setText(SecurityUiPlugin.getMessage("childNodesPageTitle")); - Composite body = form.getBody(); - GridLayout twt = new GridLayout(1, false); - twt.marginWidth = twt.marginHeight = 5; - body.setLayout(twt); - if (!currentNode.hasNodes()) { - managedForm.getToolkit().createLabel(body, - SecurityUiPlugin.getMessage("warningNoChildNode")); - } else { - nodeContentProvider = new SingleNodeAsTreeContentProvider(); - nodesViewer = createNodeViewer(body, nodeContentProvider); - nodesViewer.setInput(currentNode); - } - } catch (Exception e) { - throw new EclipseUiException( - "Unexpected error while creating child node page", e); - } - } - - protected TreeViewer createNodeViewer(Composite parent, - final ITreeContentProvider nodeContentProvider) { - - final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.BORDER); - Tree tree = tmpNodeViewer.getTree(); - tree.setLinesVisible(true); - tmpNodeViewer.getTree().setLayoutData(EclipseUiUtils.fillAll()); - tmpNodeViewer.setContentProvider(nodeContentProvider); - tmpNodeViewer.setLabelProvider(new NodeLabelProvider()); - tmpNodeViewer.addDoubleClickListener(new DClickListener()); - return tmpNodeViewer; - } - - public class DClickListener implements IDoubleClickListener { - - public void doubleClick(DoubleClickEvent event) { - if (event.getSelection() == null || event.getSelection().isEmpty()) - return; - Object obj = ((IStructuredSelection) event.getSelection()) - .getFirstElement(); - if (obj instanceof Node) { - Node node = (Node) obj; - try { - GenericNodeEditorInput gnei = new GenericNodeEditorInput( - node); - SecurityUiPlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getActivePage() - .openEditor(gnei, DefaultNodeEditor.ID); - } catch (PartInitException pie) { - throw new EclipseUiException( - "Unexepected exception while opening node editor", - pie); - } - } - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ChooseNameDialog.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ChooseNameDialog.java deleted file mode 100644 index 0c6bcb88e..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ChooseNameDialog.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** Dialog to change the current user password */ -public class ChooseNameDialog extends TitleAreaDialog { - private static final long serialVersionUID = 280139710002698692L; - private Text nameTxt; - - public ChooseNameDialog(Shell parentShell) { - super(parentShell); - setTitle("Choose name"); - } - - protected Point getInitialSize() { - return new Point(300, 250); - } - - protected Control createDialogArea(Composite parent) { - Composite dialogarea = (Composite) super.createDialogArea(parent); - dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - Composite composite = new Composite(dialogarea, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - nameTxt = createLT(composite, "Name"); - - setMessage("Choose name", IMessageProvider.INFORMATION); - parent.pack(); - return composite; - } - - /** Creates label and text. */ - protected Text createLT(Composite parent, String label) { - new Label(parent, SWT.NONE).setText(label); - Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - return text; - } - - public String getName() { - return nameTxt.getText(); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/EmptyNodePage.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/EmptyNodePage.java deleted file mode 100644 index a79f779a0..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/EmptyNodePage.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * This page is only used at editor's creation time when current node has not - * yet been set - */ -public class EmptyNodePage extends FormPage { - // private final static Log log = LogFactory.getLog(EmptyNodePage.class); - - public EmptyNodePage(FormEditor editor, String title) { - super(editor, "Empty Page", title); - } - - protected void createFormContent(IManagedForm managedForm) { - try { - ScrolledForm form = managedForm.getForm(); - GridLayout twt = new GridLayout(1, false); - twt.marginWidth = twt.marginHeight = 0; - form.getBody().setLayout(twt); - Label lbl = new Label(form.getBody(), SWT.NONE); - lbl.setText("Empty page"); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java deleted file mode 100644 index e54ad6333..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; - -/** - * An editor input based the JCR node object. - * */ - -public class GenericNodeEditorInput implements IEditorInput { - private final Node currentNode; - - // cache key properties at creation time to avoid Exception at recoring time - // when the session has been closed - private String path; - private String uid; - private String name; - - public GenericNodeEditorInput(Node currentNode) { - this.currentNode = currentNode; - try { - name = currentNode.getName(); - uid = currentNode.getIdentifier(); - path = currentNode.getPath(); - } catch (RepositoryException re) { - throw new EclipseUiException( - "unexpected error while getting node key values at creation time", - re); - } - } - - public Node getCurrentNode() { - return currentNode; - } - - public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { - return null; - } - - public boolean exists() { - return true; - } - - public ImageDescriptor getImageDescriptor() { - return null; - } - - public String getName() { - return name; - } - - public String getUid() { - return uid; - } - - public String getToolTipText() { - return path; - } - - public String getPath() { - return path; - } - - public IPersistableElement getPersistable() { - return null; - } - - /** - * equals method based on UID that is unique within a workspace and path of - * the node, thus 2 shared node that have same UID as defined in the spec - * but 2 different pathes will open two distinct editors. - * - * TODO enhance this method to support multirepository and multiworkspace - * environments - */ - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - - GenericNodeEditorInput other = (GenericNodeEditorInput) obj; - if (!getUid().equals(other.getUid())) - return false; - if (!getPath().equals(other.getPath())) - return false; - return true; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericNodePage.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericNodePage.java deleted file mode 100644 index 13bc676fa..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericNodePage.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.ListIterator; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.WorkbenchConstants; -import org.argeo.jcr.JcrUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.AbstractFormPart; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Main node editor page. Lists all properties of the current node and enable - * access and editing for some of them. - */ - -public class GenericNodePage extends FormPage implements WorkbenchConstants { - // private final static Log log = LogFactory.getLog(GenericNodePage.class); - - // local constants - private final static String JCR_PROPERTY_NAME = "jcr:name"; - - // Utils - protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT); - - // Main business Objects - private Node currentNode; - - // This page widgets - private FormToolkit tk; - private List modifyableProperties = new ArrayList(); - - public GenericNodePage(FormEditor editor, String title, Node currentNode) { - super(editor, "id", title); - this.currentNode = currentNode; - } - - protected void createFormContent(IManagedForm managedForm) { - tk = managedForm.getToolkit(); - ScrolledForm form = managedForm.getForm(); - GridLayout twt = new GridLayout(3, false); - twt.marginWidth = twt.marginHeight = 5; - - form.getBody().setLayout(twt); - createPropertiesPart(form.getBody()); - } - - private void createPropertiesPart(Composite parent) { - try { - - PropertyIterator pi = currentNode.getProperties(); - - // Initializes form part - AbstractFormPart part = new AbstractFormPart() { - public void commit(boolean onSave) { - try { - if (onSave) { - ListIterator it = modifyableProperties - .listIterator(); - while (it.hasNext()) { - // we only support Text controls for the time - // being - Text curControl = (Text) it.next(); - String value = curControl.getText(); - currentNode.setProperty((String) curControl - .getData(JCR_PROPERTY_NAME), value); - } - - // We only commit when onSave = true, - // thus it is still possible to save after a tab - // change. - super.commit(onSave); - if (currentNode.getSession().hasPendingChanges()) - currentNode.getSession().save(); - } - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while saving properties", re); - } - } - }; - - while (pi.hasNext()) { - Property prop = pi.nextProperty(); - addPropertyLine(parent, part, prop); - } - - getManagedForm().addPart(part); - } catch (RepositoryException re) { - throw new EclipseUiException( - "Error during creation of network details section", re); - } - - } - - private void addPropertyLine(Composite parent, AbstractFormPart part, - Property prop) { - try { - tk.createLabel(parent, prop.getName()); - tk.createLabel(parent, - "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]"); - - if (prop.getDefinition().isProtected()) { - tk.createLabel(parent, formatReadOnlyPropertyValue(prop)); - } else - addModifyableValueWidget(parent, part, prop); - } catch (RepositoryException re) { - throw new EclipseUiException("Cannot get property " + prop, re); - } - } - - private String formatReadOnlyPropertyValue(Property prop) { - try { - String strValue; - - if (prop.getType() == PropertyType.BINARY) - strValue = ""; - else if (prop.isMultiple()) - strValue = Arrays.asList(prop.getValues()).toString(); - else if (prop.getType() == PropertyType.DATE) - strValue = timeFormatter.format(prop.getValue().getDate() - .getTime()); - else - strValue = prop.getValue().getString(); - - return strValue; - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while formatting read only property value", - re); - } - } - - private Control addModifyableValueWidget(Composite parent, - AbstractFormPart part, Property prop) { - GridData gd; - try { - if (prop.getType() == PropertyType.STRING && !prop.isMultiple()) { - Text txt = tk.createText(parent, prop.getString(), SWT.WRAP - | SWT.MULTI); - gd = new GridData(GridData.FILL_HORIZONTAL); - txt.setLayoutData(gd); - txt.addModifyListener(new ModifiedFieldListener(part)); - txt.setData(JCR_PROPERTY_NAME, prop.getName()); - modifyableProperties.add(txt); - } else { - // unsupported property type for editing, we create a read only - // label. - return tk - .createLabel(parent, formatReadOnlyPropertyValue(prop)); - } - return null; - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while formatting read only property value", - re); - } - - } - - private class ModifiedFieldListener implements ModifyListener { - private static final long serialVersionUID = 2117484480773434646L; - private AbstractFormPart formPart; - - public ModifiedFieldListener(AbstractFormPart generalPart) { - this.formPart = generalPart; - } - - public void modifyText(ModifyEvent e) { - formPart.markDirty(); - } - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericPropertyPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericPropertyPage.java deleted file mode 100644 index 6aad31526..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/GenericPropertyPage.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Value; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.WorkbenchConstants; -import org.argeo.eclipse.ui.workbench.internal.jcr.PropertyLabelProvider; -import org.eclipse.jface.layout.TreeColumnLayout; -import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Generic editor property page. Lists all properties of current node as a - * complex tree. TODO: enable editing - */ -public class GenericPropertyPage extends FormPage implements WorkbenchConstants { - // private final static Log log = - // LogFactory.getLog(GenericPropertyPage.class); - - // Main business Objects - private Node currentNode; - - public GenericPropertyPage(FormEditor editor, String title, Node currentNode) { - super(editor, "id", title); - this.currentNode = currentNode; - } - - protected void createFormContent(IManagedForm managedForm) { - ScrolledForm form = managedForm.getForm(); - form.setText(SecurityUiPlugin.getMessage("genericNodePageTitle")); - - Composite body = form.getBody(); - FillLayout layout = new FillLayout(); - layout.marginHeight = 5; - layout.marginWidth = 5; - body.setLayout(layout); - createComplexTree(body); - // TODO TreeColumnLayout triggers a scroll issue with the form: - // The inside body is always to big and a scroll bar is shown - // Composite tableCmp = new Composite(body, SWT.NO_FOCUS); - // createComplexTree(tableCmp); - } - - private TreeViewer createComplexTree(Composite parent) { - int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION; - Tree tree = new Tree(parent, style); - TreeColumnLayout tableColumnLayout = new TreeColumnLayout(); - - createColumn(tree, tableColumnLayout, "Property", SWT.LEFT, 200, 30); - createColumn(tree, tableColumnLayout, "Value(s)", SWT.LEFT, 300, 60); - createColumn(tree, tableColumnLayout, "Attributes", SWT.LEFT, 75, 0); - // Do not apply the treeColumnLayout it does not work yet - // parent.setLayout(tableColumnLayout); - - tree.setLinesVisible(true); - tree.setHeaderVisible(true); - - TreeViewer treeViewer = new TreeViewer(tree); - treeViewer.setContentProvider(new TreeContentProvider()); - treeViewer.setLabelProvider(new PropertyLabelProvider()); - treeViewer.setInput(currentNode); - treeViewer.expandAll(); - return treeViewer; - } - - private static TreeColumn createColumn(Tree parent, - TreeColumnLayout tableColumnLayout, String name, int style, - int width, int weight) { - TreeColumn column = new TreeColumn(parent, style); - column.setText(name); - column.setWidth(width); - column.setMoveable(true); - column.setResizable(true); - tableColumnLayout.setColumnData(column, new ColumnWeightData(weight, - width, true)); - return column; - } - - // - // private void createPropertiesPart(Composite parent) { - // try { - // - // PropertyIterator pi = currentNode.getProperties(); - // - // // Initializes form part - // AbstractFormPart part = new AbstractFormPart() { - // public void commit(boolean onSave) { - // try { - // if (onSave) { - // ListIterator it = modifyableProperties - // .listIterator(); - // while (it.hasNext()) { - // // we only support Text controls for the time - // // being - // Text curControl = (Text) it.next(); - // String value = curControl.getText(); - // currentNode.setProperty((String) curControl - // .getData(JCR_PROPERTY_NAME), value); - // } - // - // // We only commit when onSave = true, - // // thus it is still possible to save after a tab - // // change. - // super.commit(onSave); - // } - // } catch (RepositoryException re) { - // throw new EclipseUiException( - // "Unexpected error while saving properties", re); - // } - // } - // }; - // - // while (pi.hasNext()) { - // Property prop = pi.nextProperty(); - // addPropertyLine(parent, part, prop); - // } - // - // getManagedForm().addPart(part); - // } catch (RepositoryException re) { - // throw new EclipseUiException( - // "Error during creation of network details section", re); - // } - // - // } - // - // private void addPropertyLine(Composite parent, AbstractFormPart part, - // Property prop) { - // try { - // tk.createLabel(parent, prop.getName()); - // tk.createLabel(parent, - // "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]"); - // - // if (prop.getDefinition().isProtected()) { - // tk.createLabel(parent, formatReadOnlyPropertyValue(prop)); - // } else - // addModifyableValueWidget(parent, part, prop); - // } catch (RepositoryException re) { - // throw new EclipseUiException("Cannot get property " + prop, re); - // } - // } - // - // private String formatReadOnlyPropertyValue(Property prop) { - // try { - // String strValue; - // - // if (prop.getType() == PropertyType.BINARY) - // strValue = ""; - // else if (prop.isMultiple()) - // strValue = Arrays.asList(prop.getValues()).toString(); - // else if (prop.getType() == PropertyType.DATE) - // strValue = timeFormatter.format(prop.getValue().getDate() - // .getTime()); - // else - // strValue = prop.getValue().getString(); - // - // return strValue; - // } catch (RepositoryException re) { - // throw new EclipseUiException( - // "Unexpected error while formatting read only property value", - // re); - // } - // } - // - // private Control addModifyableValueWidget(Composite parent, - // AbstractFormPart part, Property prop) { - // GridData gd; - // try { - // if (prop.getType() == PropertyType.STRING) { - // Text txt = tk.createText(parent, prop.getString()); - // gd = new GridData(GridData.FILL_HORIZONTAL); - // txt.setLayoutData(gd); - // txt.addModifyListener(new ModifiedFieldListener(part)); - // txt.setData(JCR_PROPERTY_NAME, prop.getName()); - // modifyableProperties.add(txt); - // } else { - // // unsupported property type for editing, we create a read only - // // label. - // return tk - // .createLabel(parent, formatReadOnlyPropertyValue(prop)); - // } - // return null; - // } catch (RepositoryException re) { - // throw new EclipseUiException( - // "Unexpected error while formatting read only property value", - // re); - // } - // - // } - - // Multiple Value Model - // protected class MultipleValueItem { - // private int index; - // private Value value; - // - // public MultipleValueItem(int index, Value value) { - // this.index = index; - // this.value = value; - // } - // - // public int getIndex() { - // return index; - // } - // - // public Object getValue() { - // return value; - // } - // } - - private class TreeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = -6162736530019406214L; - - public Object[] getElements(Object parent) { - Object[] props = null; - try { - - if (parent instanceof Node) { - Node node = (Node) parent; - PropertyIterator pi; - pi = node.getProperties(); - List propList = new ArrayList(); - while (pi.hasNext()) { - propList.add(pi.nextProperty()); - } - props = propList.toArray(); - } - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected exception while listing node properties", e); - } - return props; - } - - public Object getParent(Object child) { - return null; - } - - public Object[] getChildren(Object parent) { - Object[] result = null; - if (parent instanceof Property) { - Property prop = (Property) parent; - try { - - if (prop.isMultiple()) { - Value[] values = prop.getValues(); - // List list = new - // ArrayList(); - // for (int i = 0; i < values.length; i++) { - // MultipleValueItem mvi = new MultipleValueItem(i, - // values[i]); - // list.add(mvi); - // } - - return values; - } - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected error getting multiple values property.", - e); - } - } - return result; - } - - public boolean hasChildren(Object parent) { - try { - if (parent instanceof Property - && ((Property) parent).isMultiple()) { - return true; - } - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected exception while checking if property is multiple", - e); - } - return false; - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public void dispose() { - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ImportFileSystemWizard.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ImportFileSystemWizard.java deleted file mode 100644 index 5ac403cce..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/ImportFileSystemWizard.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import javax.jcr.Binary; -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.nodetype.NodeType; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.specific.UploadFileWizardPage; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.wizard.Wizard; - -public class ImportFileSystemWizard extends Wizard { - private final static Log log = LogFactory - .getLog(ImportFileSystemWizard.class); - - private UploadFileWizardPage importPage; - private final Node folder; - - public ImportFileSystemWizard(Node folder) { - this.folder = folder; - setWindowTitle("Import from file system"); - } - - @Override - public void addPages() { - importPage = new UploadFileWizardPage(); - addPage(importPage); - setNeedsProgressMonitor(importPage.getNeedsProgressMonitor()); - } - - /** - * Called when the user click on 'Finish' in the wizard. The real upload to - * the JCR repository is done here. - */ - @Override - public boolean performFinish() { - - // Initialization - final String objectType = importPage.getObjectType(); - final String objectPath = importPage.getObjectPath(); - - // We do not display a progress bar for one file only - if (UploadFileWizardPage.FILE_ITEM_TYPE.equals(objectType)) { - // In Rap we must force the "real" upload of the file - // importPage.performFinish(); - try { - Node fileNode = folder.addNode(importPage.getObjectName(), - NodeType.NT_FILE); - Node resNode = fileNode.addNode(Property.JCR_CONTENT, - NodeType.NT_RESOURCE); - Binary binary = null; - InputStream is = null; - try { - is = importPage.getFileInputStream(); - binary = folder.getSession().getValueFactory() - .createBinary(is); - resNode.setProperty(Property.JCR_DATA, binary); - } finally { - if (binary != null) - binary.dispose(); - IOUtils.closeQuietly(is); - } - folder.getSession().save(); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - return true; - } else if (UploadFileWizardPage.FOLDER_ITEM_TYPE.equals(objectType)) { - if (objectPath == null || !new File(objectPath).exists()) { - ErrorFeedback.show("Directory " + objectPath - + " does not exist"); - return false; - } - - Boolean failed = false; - final File dir = new File(objectPath).getAbsoluteFile(); - final Long sizeB = directorySize(dir, 0l); - final Stats stats = new Stats(); - Long begin = System.currentTimeMillis(); - try { - getContainer().run(true, true, new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) { - try { - Integer sizeKB = (int) (sizeB / FileUtils.ONE_KB); - monitor.beginTask("", sizeKB); - importDirectory(folder, dir, monitor, stats); - monitor.done(); - } catch (Exception e) { - if (e instanceof RuntimeException) - throw (RuntimeException) e; - else - throw new EclipseUiException("Cannot import " - + objectPath, e); - } - } - }); - } catch (Exception e) { - ErrorFeedback.show("Cannot import " + objectPath, e); - failed = true; - } - - Long duration = System.currentTimeMillis() - begin; - Long durationS = duration / 1000l; - String durationStr = (durationS / 60) + " min " + (durationS % 60) - + " s"; - StringBuffer message = new StringBuffer("Imported\n"); - message.append(stats.fileCount).append(" files\n"); - message.append(stats.dirCount).append(" directories\n"); - message.append(FileUtils.byteCountToDisplaySize(stats.sizeB)); - if (failed) - message.append(" of planned ").append( - FileUtils.byteCountToDisplaySize(sizeB)); - message.append("\n"); - message.append("in ").append(durationStr).append("\n"); - if (failed) - MessageDialog.openError(getShell(), "Import failed", - message.toString()); - else - MessageDialog.openInformation(getShell(), "Import successful", - message.toString()); - - return true; - } - return false; - - } - - /** Recursively computes the size of the directory in bytes. */ - protected Long directorySize(File dir, Long currentSize) { - Long size = currentSize; - File[] files = dir.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - size = directorySize(file, size); - } else { - size = size + file.length(); - } - } - return size; - } - - /** - * Import recursively a directory and its content to the repository. - */ - protected void importDirectory(Node folder, File dir, - IProgressMonitor monitor, Stats stats) { - try { - File[] files = dir.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - Node childFolder = folder.addNode(file.getName(), - NodeType.NT_FOLDER); - importDirectory(childFolder, file, monitor, stats); - folder.getSession().save(); - stats.dirCount++; - } else { - Long fileSize = file.length(); - // we skip temporary files that are created by apps when a - // file is being edited. - // TODO : make this configurable. - if (file.getName().lastIndexOf('~') != file.getName() - .length() - 1) { - - monitor.subTask(file.getName() + " (" - + FileUtils.byteCountToDisplaySize(fileSize) - + ") " + file.getCanonicalPath()); - try { - Node fileNode = folder.addNode(file.getName(), - NodeType.NT_FILE); - Node resNode = fileNode.addNode( - Property.JCR_CONTENT, NodeType.NT_RESOURCE); - Binary binary = null; - try { - binary = folder - .getSession() - .getValueFactory() - .createBinary(new FileInputStream(file)); - resNode.setProperty(Property.JCR_DATA, binary); - } finally { - if (binary != null) - binary.dispose(); - } - folder.getSession().save(); - stats.fileCount++; - stats.sizeB = stats.sizeB + fileSize; - } catch (Exception e) { - log.warn("Import of " - + file - + " (" - + FileUtils - .byteCountToDisplaySize(fileSize) - + ") failed: " + e); - folder.getSession().refresh(false); - } - monitor.worked((int) (fileSize / FileUtils.ONE_KB)); - } - } - } - } catch (Exception e) { - throw new EclipseUiException("Cannot import " + dir + " to " + folder, - e); - } - } - - static class Stats { - public Long fileCount = 0l; - public Long dirCount = 0l; - public Long sizeB = 0l; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java deleted file mode 100644 index e533dd7ce..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -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/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodeEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodeEditorInput.java deleted file mode 100644 index c562fe971..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodeEditorInput.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; - -/** - * A canonical editor input based on a path to a node. In a multirepository - * environment, path can be enriched with Repository Alias and workspace - */ - -public class NodeEditorInput implements IEditorInput { - private final String path; - - public NodeEditorInput(String path) { - this.path = path; - } - - public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { - return null; - } - - public boolean exists() { - return true; - } - - public ImageDescriptor getImageDescriptor() { - return null; - } - - public String getName() { - return path; - } - - public IPersistableElement getPersistable() { - return null; - } - - public String getToolTipText() { - return path; - } - - public String getPath() { - return path; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java deleted file mode 100644 index 0d53c53c7..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Value; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -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.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Display and edit a given node privilege. For the time being it is completely - * JackRabbit specific (and hardcoded for this) and will display an empty page - * if using any other implementation - */ -public class NodePrivilegesPage extends FormPage { - - private Node context; - - private TableViewer viewer; - - public NodePrivilegesPage(FormEditor editor, String title, Node context) { - super(editor, "NodePrivilegesPage", title); - this.context = context; - } - - protected void createFormContent(IManagedForm managedForm) { - ScrolledForm form = managedForm.getForm(); - form.setText(SecurityUiPlugin - .getMessage("nodeRightsManagementPageTitle")); - FillLayout layout = new FillLayout(); - layout.marginHeight = 5; - layout.marginWidth = 5; - form.getBody().setLayout(layout); - if (isJackRabbit()) - createRightsPart(form.getBody()); - } - - /** Creates the authorization part */ - protected void createRightsPart(Composite parent) { - Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - table.setLinesVisible(true); - table.setHeaderVisible(true); - viewer = new TableViewer(table); - - // Group / user name - TableViewerColumn column = createTableViewerColumn(viewer, - "User/Group Name", 280); - column.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -2290781173498395973L; - - public String getText(Object element) { - Node node = (Node) element; - try { - if (node.hasProperty("rep:principalName")) - return node.getProperty("rep:principalName") - .getString(); - } catch (RepositoryException e) { - throw new EclipseUiException("Unable to retrieve " - + "principal name on " + node, e); - } - return ""; - } - - public Image getImage(Object element) { - return null; - } - }); - - // Privileges - column = createTableViewerColumn(viewer, "Assigned privileges", 300); - column.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -2290781173498395973L; - private String propertyName = "rep:privileges"; - - public String getText(Object element) { - Node node = (Node) element; - try { - if (node.hasProperty(propertyName)) { - String separator = ", "; - Value[] langs = node.getProperty(propertyName) - .getValues(); - StringBuilder builder = new StringBuilder(); - for (Value val : langs) { - String currStr = val.getString(); - builder.append(currStr).append(separator); - } - if (builder.lastIndexOf(separator) >= 0) - return builder.substring(0, builder.length() - - separator.length()); - else - return builder.toString(); - - } - } catch (RepositoryException e) { - throw new EclipseUiException("Unable to retrieve " - + "privileges on " + node, e); - } - return ""; - } - - public Image getImage(Object element) { - return null; - } - }); - - // Relevant node - column = createTableViewerColumn(viewer, "Relevant node", 300); - column.setLabelProvider(new ColumnLabelProvider() { - /** - * - */ - private static final long serialVersionUID = 4245522992038244849L; - - public String getText(Object element) { - Node node = (Node) element; - try { - return node.getParent().getParent().getPath(); - } catch (RepositoryException e) { - throw new EclipseUiException("Unable get path for " + node, - e); - } - } - - public Image getImage(Object element) { - return null; - } - }); - - viewer.setContentProvider(new RightsContentProvider()); - viewer.setInput(getEditorSite()); - } - - protected TableViewerColumn createTableViewerColumn(TableViewer viewer, - String title, int bound) { - final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, - SWT.NONE); - final TableColumn column = viewerColumn.getColumn(); - column.setText(title); - column.setWidth(bound); - column.setResizable(true); - column.setMoveable(true); - return viewerColumn; - } - - private class RightsContentProvider implements IStructuredContentProvider { - private static final long serialVersionUID = -7631476348552802706L; - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - // TODO JackRabbit specific retrieval of authorization. Clean and - // generalize - public Object[] getElements(Object inputElement) { - try { - List privs = new ArrayList(); - - Node currNode = context; - String currPath = currNode.getPath(); - - loop: while (true) { - if (currNode.hasNode("rep:policy")) { - NodeIterator nit = currNode.getNode("rep:policy") - .getNodes(); - while (nit.hasNext()) { - Node currPrivNode = nit.nextNode(); - if (currPrivNode.getName().startsWith("allow")) - privs.add(currPrivNode); - } - } - if ("/".equals(currPath)) - break loop; - else { - currNode = currNode.getParent(); - currPath = currNode.getPath(); - } - } - - // AccessControlManager acm = context.getSession() - // .getAccessControlManager(); - // AccessControlPolicyIterator acpi = acm - // .getApplicablePolicies(context.getPath()); - // - // List acps = new - // ArrayList(); - // try { - // while (true) { - // Object obj = acpi.next(); - // acps.add((AccessControlPolicy) obj); - // } - // } catch (Exception e) { - // // No more elements - // } - // - // AccessControlList acl = ((AccessControlList) acps.get(0)); - // AccessControlEntry[] entries = acl.getAccessControlEntries(); - - return privs.toArray(); - } catch (Exception e) { - throw new EclipseUiException( - "Cannot retrieve authorization for " + context, e); - } - } - } - - // simply check if we are using jackrabbit without adding code dependencies - private boolean isJackRabbit() { - try { - String cname = context.getSession().getClass().getName(); - return cname.startsWith("org.apache.jackrabbit"); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Cannot check JCR implementation used on " + context, e); - } - } - -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java deleted file mode 100644 index 76a81c7c6..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; -import javax.jcr.Value; -import javax.jcr.nodetype.NodeType; -import javax.jcr.version.Version; -import javax.jcr.version.VersionHistory; -import javax.jcr.version.VersionIterator; -import javax.jcr.version.VersionManager; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.WorkbenchConstants; -import org.argeo.eclipse.ui.workbench.internal.jcr.FullVersioningTreeContentProvider; -import org.argeo.eclipse.ui.workbench.internal.jcr.GenericNodeDoubleClickListener; -import org.argeo.eclipse.ui.workbench.internal.jcr.VersionLabelProvider; -import org.argeo.jcr.JcrUtils; -import org.argeo.jcr.PropertyDiff; -import org.argeo.jcr.VersionDiff; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.AbstractFormPart; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.eclipse.ui.forms.widgets.TableWrapData; -import org.eclipse.ui.forms.widgets.TableWrapLayout; - -/** - * Offers two main sections : one to display a text area with a summary of all - * variations between a version and its predecessor and one tree view that - * enable browsing - * */ -public class NodeVersionHistoryPage extends FormPage implements - WorkbenchConstants { - // private final static Log log = LogFactory - // .getLog(NodeVersionHistoryPage.class); - - // Utils - protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT); - - // business objects - private Node currentNode; - - // this page UI components - private FullVersioningTreeContentProvider nodeContentProvider; - private TreeViewer nodesViewer; - private FormToolkit tk; - - public NodeVersionHistoryPage(FormEditor editor, String title, - Node currentNode) { - super(editor, "NodeVersionHistoryPage", title); - this.currentNode = currentNode; - } - - protected void createFormContent(IManagedForm managedForm) { - ScrolledForm form = managedForm.getForm(); - form.setText(SecurityUiPlugin.getMessage("nodeVersionHistoryPageTitle")); - tk = managedForm.getToolkit(); - GridLayout twt = new GridLayout(1, false); - twt.marginWidth = twt.marginHeight = 5; - Composite body = form.getBody(); - body.setLayout(twt); - - try { - if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) { - tk.createLabel(body, - SecurityUiPlugin.getMessage("warningUnversionableNode")); - } else { - createHistorySection(form.getBody()); - createTreeSection(form.getBody()); - } - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected error while checking if node is versionable", e); - } - } - - protected void createTreeSection(Composite parent) { - // Section Layout & MetaData - Section section = tk.createSection(parent, Section.TWISTIE); - section.setLayoutData(new GridData(GridData.FILL_BOTH)); - section.setText(SecurityUiPlugin.getMessage("versionTreeSectionTitle")); - - // Section Body - Composite body = tk.createComposite(section, SWT.FILL); - // WARNING : 2 following lines are compulsory or body won't be - // displayed. - body.setLayout(new GridLayout()); - section.setClient(body); - - body.setLayoutData(new GridData(GridData.FILL_BOTH)); - section.setExpanded(true); - - nodeContentProvider = new FullVersioningTreeContentProvider(); - nodesViewer = createNodeViewer(body, nodeContentProvider); - nodesViewer.setInput(currentNode); - } - - protected TreeViewer createNodeViewer(Composite parent, - final ITreeContentProvider nodeContentProvider) { - - final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI); - - tmpNodeViewer.getTree().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - tmpNodeViewer.setContentProvider(nodeContentProvider); - tmpNodeViewer.setLabelProvider(new VersionLabelProvider()); - tmpNodeViewer - .addDoubleClickListener(new GenericNodeDoubleClickListener( - tmpNodeViewer)); - return tmpNodeViewer; - } - - protected void createHistorySection(Composite parent) { - - // Section Layout - Section section = tk.createSection(parent, Section.TWISTIE); - section.setLayoutData(new GridData(TableWrapData.FILL_GRAB)); - TableWrapLayout twt = new TableWrapLayout(); - section.setLayout(twt); - - // Set title of the section - section.setText(SecurityUiPlugin - .getMessage("versionHistorySectionTitle")); - - final Text styledText = tk.createText(section, "", SWT.FULL_SELECTION - | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); - styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - section.setClient(styledText); - refreshHistory(styledText); - styledText.setEditable(false); - section.setExpanded(false); - - AbstractFormPart part = new AbstractFormPart() { - public void commit(boolean onSave) { - } - - public void refresh() { - super.refresh(); - refreshHistory(styledText); - } - }; - getManagedForm().addPart(part); - } - - protected void refreshHistory(Text styledText) { - try { - List lst = listHistoryDiff(); - StringBuffer main = new StringBuffer(""); - - for (int i = lst.size() - 1; i >= 0; i--) { - if (i == 0) - main.append("Creation ("); - else - main.append("Update " + i + " ("); - - if (lst.get(i).getUserId() != null) - main.append("UserId : " + lst.get(i).getUserId()); - - if (lst.get(i).getUserId() != null - && lst.get(i).getUpdateTime() != null) - main.append(", "); - - if (lst.get(i).getUpdateTime() != null) - main.append("Date : " - + timeFormatter.format(lst.get(i).getUpdateTime() - .getTime()) + ")\n"); - - StringBuffer buf = new StringBuffer(""); - Map diffs = lst.get(i).getDiffs(); - for (String prop : diffs.keySet()) { - PropertyDiff pd = diffs.get(prop); - // String propName = pd.getRelPath(); - Value refValue = pd.getReferenceValue(); - Value newValue = pd.getNewValue(); - String refValueStr = ""; - String newValueStr = ""; - - if (refValue != null) { - if (refValue.getType() == PropertyType.DATE) { - refValueStr = timeFormatter.format(refValue - .getDate().getTime()); - } else - refValueStr = refValue.getString(); - } - if (newValue != null) { - if (newValue.getType() == PropertyType.DATE) { - newValueStr = timeFormatter.format(newValue - .getDate().getTime()); - } else - newValueStr = newValue.getString(); - } - - if (pd.getType() == PropertyDiff.MODIFIED) { - buf.append(prop).append(": "); - buf.append(refValueStr); - buf.append(" > "); - buf.append(newValueStr); - buf.append("\n"); - } else if (pd.getType() == PropertyDiff.ADDED - && !"".equals(newValueStr)) { - // we don't list property that have been added with an - // empty string as value - buf.append(prop).append(": "); - buf.append(" + "); - buf.append(newValueStr); - buf.append("\n"); - } else if (pd.getType() == PropertyDiff.REMOVED) { - buf.append(prop).append(": "); - buf.append(" - "); - buf.append(refValueStr); - buf.append("\n"); - } - } - buf.append("\n"); - main.append(buf); - } - styledText.setText(main.toString()); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot generate history for node", e); - } - - } - - public List listHistoryDiff() { - try { - List res = new ArrayList(); - VersionManager versionManager = currentNode.getSession() - .getWorkspace().getVersionManager(); - VersionHistory versionHistory = versionManager - .getVersionHistory(currentNode.getPath()); - - VersionIterator vit = versionHistory.getAllLinearVersions(); - while (vit.hasNext()) { - Version version = vit.nextVersion(); - Node node = version.getFrozenNode(); - Version predecessor = null; - try { - predecessor = version.getLinearPredecessor(); - } catch (Exception e) { - // no predecessor seems to throw an exception even if it - // shouldn't... - } - if (predecessor == null) {// original - } else { - Map diffs = JcrUtils.diffProperties( - predecessor.getFrozenNode(), node); - if (!diffs.isEmpty()) { - String lastUserName = null; - Calendar lastUpdate = null; - try { - if (currentNode - .isNodeType(NodeType.MIX_LAST_MODIFIED)) { - lastUserName = node.getProperty( - Property.JCR_LAST_MODIFIED_BY) - .getString(); - lastUpdate = node.getProperty( - Property.JCR_LAST_MODIFIED).getDate(); - } else - lastUpdate = version.getProperty( - Property.JCR_CREATED).getDate(); - - } catch (Exception e) { - // Silent that info is optional - } - VersionDiff vd = new VersionDiff(lastUserName, - lastUpdate, diffs); - res.add(vd); - } - } - } - return res; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot generate history for node "); - } - - } - - @Override - public void setActive(boolean active) { - super.setActive(active); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java deleted file mode 100644 index e93b7ea73..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.jcr.parts; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; - -/** - * An editor input based on three strings define a node : - *
    - *
  • complete path to the node
  • - *
  • the workspace name
  • - *
  • the repository alias
  • - *
- * In a single workspace and/or repository environment, name and alias can be - * null. - * - * Note : unused for the time being. - */ - -public class StringNodeEditorInput implements IEditorInput { - private final String path; - private final String repositoryAlias; - private final String workspaceName; - - /** - * In order to implement a generic explorer that supports remote and multi - * workspaces repositories, node path can be detailed by these strings. - * - * @param repositoryAlias - * : can be null - * @param workspaceName - * : can be null - * @param path - */ - public StringNodeEditorInput(String repositoryAlias, String workspaceName, - String path) { - this.path = path; - this.repositoryAlias = repositoryAlias; - this.workspaceName = workspaceName; - } - - public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { - return null; - } - - public boolean exists() { - return true; - } - - public ImageDescriptor getImageDescriptor() { - return null; - } - - public String getName() { - return path; - } - - public String getRepositoryAlias() { - return repositoryAlias; - } - - public String getWorkspaceName() { - return workspaceName; - } - - public IPersistableElement getPersistable() { - return null; - } - - public String getToolTipText() { - return path; - } - - public String getPath() { - return path; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - - StringNodeEditorInput other = (StringNodeEditorInput) obj; - - if (!path.equals(other.getPath())) - return false; - - String own = other.getWorkspaceName(); - if ((workspaceName == null && own != null) - || (workspaceName != null && (own == null || !workspaceName - .equals(own)))) - return false; - - String ora = other.getRepositoryAlias(); - if ((repositoryAlias == null && ora != null) - || (repositoryAlias != null && (ora == null || !repositoryAlias - .equals(ora)))) - return false; - - return true; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/users/UsersImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/users/UsersImages.java deleted file mode 100644 index c1b4d5753..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/users/UsersImages.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.internal.users; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.swt.graphics.Image; - -/** Specific users icons. TODO centralize and use an image registry */ -public class UsersImages { - private final static String PREFIX = "icons/"; - - public final static Image ICON_USER = SecurityUiPlugin.getImageDescriptor( - PREFIX + "user.gif").createImage(); - public final static Image ICON_GROUP = SecurityUiPlugin.getImageDescriptor( - PREFIX + "users.gif").createImage(); - public final static Image ICON_ROLE = SecurityUiPlugin.getImageDescriptor( - PREFIX + "role.gif").createImage(); -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/users/UsersUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/users/UsersUtils.java deleted file mode 100644 index 397ecdebd..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/internal/users/UsersUtils.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.argeo.eclipse.ui.workbench.internal.users; - -import java.security.AccessController; -import java.util.List; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; -import javax.security.auth.Subject; -import javax.security.auth.x500.X500Principal; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.osgi.useradmin.LdifName; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; - -/** Utility methods to manage user concepts in the ui.workbench bundle */ -public class UsersUtils { - // TODO this constant is defined in the CMS - public final static String ROLES_BASEDN = "ou=roles,ou=node"; - - public final static boolean isCurrentUser(User user) { - String userName = getProperty(user, LdifName.dn.name()); - try { - LdapName selfUserName = getLdapName(); - LdapName userLdapName = new LdapName(userName); - if (userLdapName.equals(selfUserName)) - return true; - else - return false; - } catch (InvalidNameException e) { - throw new EclipseUiException("User " + user + " has an unvalid dn: " - + userName, e); - } - } - - public final static LdapName getLdapName() { - Subject subject = Subject.getSubject(AccessController.getContext()); - String name = subject.getPrincipals(X500Principal.class).iterator() - .next().toString(); - LdapName dn; - try { - dn = new LdapName(name); - } catch (InvalidNameException e) { - throw new EclipseUiException("Invalid user dn " + name, e); - } - return dn; - } - - public final static String getCommonName(User user) { - return getProperty(user, LdifName.cn.name()); - } - - /** Simply retrieves a display name of the relevant domain */ - public final static String getDomainName(User user) { - String dn = (String) user.getProperties().get(LdifName.dn.name()); - if (dn.endsWith(ROLES_BASEDN)) - return "System roles"; - try { - LdapName name; - name = new LdapName(dn); - List rdns = name.getRdns(); - String dname = null; - int i = 0; - loop: while (i < rdns.size()) { - Rdn currrRdn = rdns.get(i); - if (!"dc".equals(currrRdn.getType())) - break loop; - else { - String currVal = (String) currrRdn.getValue(); - dname = dname == null ? currVal : currVal + "." + dname; - } - i++; - } - return dname; - } catch (InvalidNameException e) { - throw new EclipseUiException("Unable to get domain name for " + dn, e); - } - } - - public final static String getProperty(Role role, String key) { - Object obj = role.getProperties().get(key); - if (obj != null) - return (String) obj; - else - return ""; - } - - /* - * INTERNAL METHODS: Below methods are meant to stay here and are not part - * of a potential generic backend to manage the useradmin - */ - public final static boolean notNull(String string) { - if (string == null) - return false; - else - return !"".equals(string.trim()); - } - -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/DefaultNodeEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/DefaultNodeEditor.java deleted file mode 100644 index fd7302569..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/DefaultNodeEditor.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.jcr; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; -import javax.jcr.security.AccessControlManager; -import javax.jcr.security.Privilege; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.ChildNodesPage; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.GenericNodeEditorInput; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.GenericNodePage; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.GenericPropertyPage; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.NodePrivilegesPage; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.NodeVersionHistoryPage; -import org.argeo.jcr.JcrUtils; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.forms.editor.FormEditor; - -/** Default form editor for a Jcr {@link Node} */ -public class DefaultNodeEditor extends FormEditor { - private static final long serialVersionUID = 8322127770921612239L; - - // private final static Log log = - // LogFactory.getLog(GenericNodeEditor.class); - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".defaultNodeEditor"; - - private Node currentNode; - - private GenericNodePage genericNodePage; - private GenericPropertyPage genericPropertyPage; - private ChildNodesPage childNodesPage; - private NodePrivilegesPage nodeRightsManagementPage; - private NodeVersionHistoryPage nodeVersionHistoryPage; - - public void init(IEditorSite site, IEditorInput input) - throws PartInitException { - super.init(site, input); - GenericNodeEditorInput nei = (GenericNodeEditorInput) getEditorInput(); - currentNode = nei.getCurrentNode(); - this.setPartName(JcrUtils.lastPathElement(nei.getPath())); - } - - @Override - protected void addPages() { - try { - genericPropertyPage = new GenericPropertyPage(this, - SecurityUiPlugin.getMessage("genericNodePageTitle"), - currentNode); - addPage(genericPropertyPage); - - childNodesPage = new ChildNodesPage(this, - SecurityUiPlugin.getMessage("childNodesPageTitle"), - currentNode); - addPage(childNodesPage); - - AccessControlManager accessControlManager = currentNode - .getSession().getAccessControlManager(); - List privileges = new ArrayList(); - privileges.add(accessControlManager - .privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL)); - if (accessControlManager.hasPrivileges(currentNode.getPath(), - privileges.toArray(new Privilege[0]))) { - nodeRightsManagementPage = new NodePrivilegesPage(this, - SecurityUiPlugin - .getMessage("nodeRightsManagementPageTitle"), - currentNode); - addPage(nodeRightsManagementPage); - } - if (currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) { - nodeVersionHistoryPage = new NodeVersionHistoryPage(this, - SecurityUiPlugin - .getMessage("nodeVersionHistoryPageTitle"), - currentNode); - addPage(nodeVersionHistoryPage); - } - - privileges = new ArrayList(); - privileges.add(accessControlManager - .privilegeFromName(Privilege.JCR_ALL)); - if (accessControlManager.hasPrivileges(currentNode.getPath(), - privileges.toArray(new Privilege[0]))) { - genericNodePage = new GenericNodePage( - this, - SecurityUiPlugin.getMessage("propertyEditorPageTitle"), - currentNode); - addPage(genericNodePage); - } - - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot get node info for " - + currentNode, e); - } catch (PartInitException e) { - throw new EclipseUiException("Cannot add page " - + "on node editor for " + currentNode, e); - } - } - - @Override - public void doSaveAs() { - // unused compulsory method - } - - @Override - public void doSave(IProgressMonitor monitor) { - try { - // Automatically commit all pages of the editor - commitPages(true); - firePropertyChange(PROP_DIRTY); - } catch (Exception e) { - throw new EclipseUiException("Error while saving node", e); - } - - } - - @Override - public boolean isSaveAsAllowed() { - return true; - } - - Node getCurrentNode() { - return currentNode; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/GenericJcrQueryEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/GenericJcrQueryEditor.java deleted file mode 100644 index 653db977b..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/GenericJcrQueryEditor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.jcr; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.workbench.internal.jcr.parts.AbstractJcrQueryEditor; -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; - -/** Enables end user to type and execute any JCR query. */ -public class GenericJcrQueryEditor extends AbstractJcrQueryEditor { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".genericJcrQueryEditor"; - - 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() { - private static final long serialVersionUID = -918256291554301699L; - - 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/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserPerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserPerspective.java deleted file mode 100644 index 065ae524e..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserPerspective.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.jcr; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** Base perspective for the Jcr browser */ -public class JcrBrowserPerspective implements IPerspectiveFactory { - - public void createInitialLayout(IPageLayout layout) { - layout.setEditorAreaVisible(true); - IFolderLayout upperLeft = layout.createFolder( - SecurityUiPlugin.PLUGIN_ID + ".upperLeft", IPageLayout.LEFT, - 0.4f, layout.getEditorArea()); - upperLeft.addView(JcrBrowserView.ID); - - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java deleted file mode 100644 index c30082765..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.jcr; - -import java.util.List; - -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.Value; -import javax.jcr.observation.Event; -import javax.jcr.observation.EventListener; -import javax.jcr.observation.ObservationManager; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiException; -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.workbench.internal.jcr.GenericNodeDoubleClickListener; -import org.argeo.eclipse.ui.workbench.internal.jcr.JcrBrowserUtils; -import org.argeo.eclipse.ui.workbench.internal.jcr.NodeContentProvider; -import org.argeo.eclipse.ui.workbench.internal.jcr.NodeLabelProvider; -import org.argeo.eclipse.ui.workbench.internal.jcr.PropertiesContentProvider; -import org.argeo.eclipse.ui.workbench.internal.jcr.model.SingleJcrNodeElem; -import org.argeo.jcr.RepositoryRegister; -import org.argeo.node.security.Keyring; -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; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -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.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.part.ViewPart; - -/** - * Basic View to display a sash form to browse a JCR compliant multiple - * repository environment - */ -public class JcrBrowserView extends ViewPart { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".jcrBrowserView"; - private boolean sortChildNodes = true; - - /* DEPENDENCY INJECTION */ - private Keyring keyring; - private RepositoryRegister repositoryRegister; - private RepositoryFactory repositoryFactory; - private Repository nodeRepository; - - // Current user session on the "Argeo node" default workspace - private Session userSession; - - // This page widgets - private TreeViewer nodesViewer; - private NodeContentProvider nodeContentProvider; - private TableViewer propertiesViewer; - private EventListener resultsObserver; - - @Override - public void createPartControl(Composite parent) { - parent.setLayout(new FillLayout()); - SashForm sashForm = new SashForm(parent, SWT.VERTICAL); - sashForm.setSashWidth(4); - sashForm.setLayout(new FillLayout()); - - // Create the tree on top of the view - Composite top = new Composite(sashForm, SWT.NONE); - GridLayout gl = new GridLayout(1, false); - top.setLayout(gl); - - try { - this.userSession = this.nodeRepository.login(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot open user session", e); - } - - nodeContentProvider = new NodeContentProvider(userSession, keyring, - repositoryRegister, repositoryFactory, sortChildNodes); - - // nodes viewer - nodesViewer = createNodeViewer(top, nodeContentProvider); - - // context menu : it is completely defined in the plugin.xml file. - MenuManager menuManager = new MenuManager(); - Menu menu = menuManager.createContextMenu(nodesViewer.getTree()); - - nodesViewer.getTree().setMenu(menu); - getSite().registerContextMenu(menuManager, nodesViewer); - getSite().setSelectionProvider(nodesViewer); - - nodesViewer.setInput(getViewSite()); - - // Create the property viewer on the bottom - Composite bottom = new Composite(sashForm, SWT.NONE); - bottom.setLayout(new GridLayout(1, false)); - propertiesViewer = createPropertiesViewer(bottom); - - sashForm.setWeights(getWeights()); - nodesViewer.setComparer(new NodeViewerComparer()); - } - - public void refresh(Object obj) { - // Enable full refresh from a command when no element of the tree is - // selected - if (obj == null) { - Object[] elements = nodeContentProvider.getElements(null); - for (Object el : elements) { - if (el instanceof TreeParent) - JcrBrowserUtils.forceRefreshIfNeeded((TreeParent) el); - getNodeViewer().refresh(el); - } - } else - getNodeViewer().refresh(obj); - } - - /** - * To be overridden to adapt size of form and result frames. - */ - protected int[] getWeights() { - return new int[] { 70, 30 }; - } - - protected TreeViewer createNodeViewer(Composite parent, - final ITreeContentProvider nodeContentProvider) { - - final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI); - - tmpNodeViewer.getTree().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - tmpNodeViewer.setContentProvider(nodeContentProvider); - tmpNodeViewer.setLabelProvider(new NodeLabelProvider()); - tmpNodeViewer - .addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - if (!event.getSelection().isEmpty()) { - IStructuredSelection sel = (IStructuredSelection) event - .getSelection(); - Object firstItem = sel.getFirstElement(); - if (firstItem instanceof SingleJcrNodeElem) - propertiesViewer - .setInput(((SingleJcrNodeElem) firstItem) - .getNode()); - } else { - propertiesViewer.setInput(getViewSite()); - } - } - }); - - resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay()); - if (keyring != null) - try { - ObservationManager observationManager = userSession - .getWorkspace().getObservationManager(); - observationManager.addEventListener(resultsObserver, - Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/", - true, null, null, false); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot register listeners", e); - } - - tmpNodeViewer - .addDoubleClickListener(new GenericNodeDoubleClickListener( - tmpNodeViewer)); - return tmpNodeViewer; - } - - protected TableViewer createPropertiesViewer(Composite parent) { - propertiesViewer = new TableViewer(parent); - propertiesViewer.getTable().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - propertiesViewer.getTable().setHeaderVisible(true); - propertiesViewer.setContentProvider(new PropertiesContentProvider()); - TableViewerColumn col = new TableViewerColumn(propertiesViewer, - SWT.NONE); - col.getColumn().setText("Name"); - col.getColumn().setWidth(200); - col.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -6684361063107478595L; - - public String getText(Object element) { - try { - return ((Property) element).getName(); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected exception in label provider", e); - } - } - }); - col = new TableViewerColumn(propertiesViewer, SWT.NONE); - col.getColumn().setText("Value"); - col.getColumn().setWidth(400); - col.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -8201994187693336657L; - - public String getText(Object element) { - try { - Property property = (Property) element; - if (property.getType() == PropertyType.BINARY) - return ""; - else if (property.isMultiple()) { - StringBuffer buf = new StringBuffer("["); - Value[] values = property.getValues(); - for (int i = 0; i < values.length; i++) { - if (i != 0) - buf.append(", "); - buf.append(values[i].getString()); - } - buf.append(']'); - return buf.toString(); - } else - return property.getValue().getString(); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected exception in label provider", e); - } - } - }); - col = new TableViewerColumn(propertiesViewer, SWT.NONE); - col.getColumn().setText("Type"); - col.getColumn().setWidth(200); - col.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -6009599998150286070L; - - public String getText(Object element) { - try { - return PropertyType.nameFromValue(((Property) element) - .getType()); - } catch (RepositoryException e) { - throw new EclipseUiException( - "Unexpected exception in label provider", e); - } - } - }); - propertiesViewer.setInput(getViewSite()); - return propertiesViewer; - } - - @Override - public void dispose() { - super.dispose(); - } - - protected TreeViewer getNodeViewer() { - return nodesViewer; - } - - /** - * Resets the tree content provider - * - * @param sortChildNodes - * if true the content provider will use a comparer to sort nodes - * that might slow down the display - * */ - public void setSortChildNodes(boolean sortChildNodes) { - this.sortChildNodes = sortChildNodes; - ((NodeContentProvider) nodesViewer.getContentProvider()) - .setSortChildren(sortChildNodes); - nodesViewer.setInput(getViewSite()); - } - - /** Notifies the current view that a node has been added */ - public void nodeAdded(TreeParent parentNode) { - // insure that Ui objects have been correctly created: - JcrBrowserUtils.forceRefreshIfNeeded(parentNode); - getNodeViewer().refresh(parentNode); - getNodeViewer().expandToLevel(parentNode, 1); - } - - /** Notifies the current view that a node has been removed */ - 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) { - super(display); - } - - @Override - protected Boolean willProcessInUiThread(List events) - throws RepositoryException { - for (Event event : events) { - if (getLog().isTraceEnabled()) - getLog().debug("Received event " + event); - String path = event.getPath(); - int index = path.lastIndexOf('/'); - String propertyName = path.substring(index + 1); - if (getLog().isTraceEnabled()) - getLog().debug("Concerned property " + propertyName); - } - return false; - } - - protected void onEventInUiThread(List events) - throws RepositoryException { - if (getLog().isTraceEnabled()) - getLog().trace("Refresh result list"); - nodesViewer.refresh(); - } - - } - - public boolean getSortChildNodes() { - return sortChildNodes; - } - - @Override - public void setFocus() { - getNodeViewer().getTree().setFocus(); - } - - /* DEPENDENCY INJECTION */ - public void setRepositoryRegister(RepositoryRegister repositoryRegister) { - this.repositoryRegister = repositoryRegister; - } - - public void setKeyring(Keyring keyring) { - this.keyring = keyring; - } - - public void setRepositoryFactory(RepositoryFactory repositoryFactory) { - this.repositoryFactory = repositoryFactory; - } - - public void setNodeRepository(Repository nodeRepository) { - this.nodeRepository = nodeRepository; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrImages.java deleted file mode 100644 index d117f6e18..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrImages.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.jcr; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.swt.graphics.Image; - -/** Shared icons. */ -public class JcrImages { - public final static Image NODE = SecurityUiPlugin.getImageDescriptor( - "icons/node.gif").createImage(); - public final static Image FOLDER = SecurityUiPlugin.getImageDescriptor( - "icons/folder.gif").createImage(); - public final static Image FILE = SecurityUiPlugin.getImageDescriptor( - "icons/file.gif").createImage(); - public final static Image BINARY = SecurityUiPlugin.getImageDescriptor( - "icons/binary.png").createImage(); - public final static Image HOME = SecurityUiPlugin.getImageDescriptor( - "icons/home.gif").createImage(); - public final static Image SORT = SecurityUiPlugin.getImageDescriptor( - "icons/sort.gif").createImage(); - public final static Image REMOVE = SecurityUiPlugin.getImageDescriptor( - "icons/remove.gif").createImage(); - - public final static Image REPOSITORIES = SecurityUiPlugin - .getImageDescriptor("icons/repositories.gif").createImage(); - public final static Image REPOSITORY_DISCONNECTED = SecurityUiPlugin - .getImageDescriptor("icons/repository_disconnected.gif") - .createImage(); - public final static Image REPOSITORY_CONNECTED = SecurityUiPlugin - .getImageDescriptor("icons/repository_connected.gif").createImage(); - public final static Image REMOTE_DISCONNECTED = SecurityUiPlugin - .getImageDescriptor("icons/remote_disconnected.gif").createImage(); - public final static Image REMOTE_CONNECTED = SecurityUiPlugin - .getImageDescriptor("icons/remote_connected.gif").createImage(); - public final static Image WORKSPACE_DISCONNECTED = SecurityUiPlugin - .getImageDescriptor("icons/workspace_disconnected.png") - .createImage(); - public final static Image WORKSPACE_CONNECTED = SecurityUiPlugin - .getImageDescriptor("icons/workspace_connected.png").createImage(); - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrPreferenceStore.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrPreferenceStore.java deleted file mode 100644 index 406baf929..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrPreferenceStore.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.jcr; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Properties; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.version.VersionManager; - -import org.apache.commons.io.IOUtils; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.jcr.JcrUtils; -import org.argeo.node.ArgeoNames; -import org.argeo.node.ArgeoTypes; -import org.argeo.node.NodeUtils; -import org.eclipse.jface.preference.PreferenceStore; -import org.osgi.framework.BundleContext; - -/** - * Persist preferences as key/value pairs under ~/argeo:preferences.
- * TODO: better integrate JCR and Eclipse:
- * - typing
- * - use eclipse preferences
- * - better integrate with ScopedPreferenceStore provided by RAP - */ -public class JcrPreferenceStore extends PreferenceStore implements ArgeoNames { - private static final long serialVersionUID = 1854011367784598758L; - - private Session session; - private BundleContext bundleContext; - - /** Retrieves the preference node */ - protected Node getPreferenceNode() { - try { - if (session.hasPendingChanges()) - session.save(); - Node userHome = NodeUtils.getUserHome(session); - if (userHome == null) - throw new EclipseUiException("No user home for " - + session.getUserID()); - Node preferences; - if (!userHome.hasNode(ARGEO_PREFERENCES)) { - preferences = userHome.addNode(ARGEO_PREFERENCES); - preferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE); - session.save(); - } else - preferences = userHome.getNode(ARGEO_PREFERENCES); - - String pluginPreferencesName = bundleContext.getBundle() - .getSymbolicName(); - Node pluginPreferences; - if (!preferences.hasNode(pluginPreferencesName)) { - VersionManager vm = session.getWorkspace().getVersionManager(); - vm.checkout(preferences.getPath()); - pluginPreferences = preferences.addNode(pluginPreferencesName); - pluginPreferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE); - session.save(); - vm.checkin(preferences.getPath()); - } else - pluginPreferences = preferences.getNode(pluginPreferencesName); - return pluginPreferences; - } catch (RepositoryException e) { - e.printStackTrace(); - JcrUtils.discardQuietly(session); - throw new EclipseUiException("Cannot retrieve preferences", e); - } - - } - - @Override - public void load() throws IOException { - ByteArrayOutputStream out = null; - ByteArrayInputStream in = null; - try { - Properties props = new Properties(); - PropertyIterator it = getPreferenceNode().getProperties(); - while (it.hasNext()) { - Property p = it.nextProperty(); - if (!p.isMultiple() && !p.getDefinition().isProtected()) { - props.setProperty(p.getName(), p.getValue().getString()); - } - } - out = new ByteArrayOutputStream(); - props.store(out, ""); - in = new ByteArrayInputStream(out.toByteArray()); - load(in); - } catch (Exception e) { - e.printStackTrace(); - throw new EclipseUiException("Cannot load preferences", e); - } finally { - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(out); - } - } - - @Override - public void save() throws IOException { - ByteArrayOutputStream out = null; - ByteArrayInputStream in = null; - Node pluginPreferences = null; - try { - out = new ByteArrayOutputStream(); - save(out, ""); - in = new ByteArrayInputStream(out.toByteArray()); - Properties props = new Properties(); - props.load(in); - pluginPreferences = getPreferenceNode(); - VersionManager vm = pluginPreferences.getSession().getWorkspace() - .getVersionManager(); - vm.checkout(pluginPreferences.getPath()); - for (Object key : props.keySet()) { - String name = key.toString(); - String value = props.getProperty(name); - pluginPreferences.setProperty(name, value); - } - JcrUtils.updateLastModified(pluginPreferences); - pluginPreferences.getSession().save(); - vm.checkin(pluginPreferences.getPath()); - } catch (Exception e) { - JcrUtils.discardUnderlyingSessionQuietly(pluginPreferences); - throw new EclipseUiException("Cannot save preferences", e); - } finally { - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(out); - } - } - - public void init() { - try { - load(); - } catch (IOException e) { - throw new EclipseUiException("Cannot initialize preference store", e); - } - } - - public void setSession(Session session) { - this.session = session; - } - - public void setBundleContext(BundleContext bundleContext) { - this.bundleContext = bundleContext; - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/BundleNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/BundleNode.java deleted file mode 100644 index 8661331b2..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/BundleNode.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.argeo.eclipse.ui.workbench.osgi; - -import org.argeo.eclipse.ui.TreeParent; -import org.osgi.framework.Bundle; -import org.osgi.framework.ServiceReference; - -/** A tree element representing a {@link Bundle} */ -class BundleNode extends TreeParent { - private final Bundle bundle; - - public BundleNode(Bundle bundle) { - this(bundle, false); - } - - @SuppressWarnings("rawtypes") - public BundleNode(Bundle bundle, boolean hasChildren) { - super(bundle.getSymbolicName()); - this.bundle = bundle; - - if (hasChildren) { - // REFERENCES - ServiceReference[] usedServices = bundle.getServicesInUse(); - if (usedServices != null) { - for (ServiceReference sr : usedServices) { - if (sr != null) - addChild(new ServiceReferenceNode(sr, false)); - } - } - - // SERVICES - ServiceReference[] registeredServices = bundle - .getRegisteredServices(); - if (registeredServices != null) { - for (ServiceReference sr : registeredServices) { - if (sr != null) - addChild(new ServiceReferenceNode(sr, true)); - } - } - } - - } - - Bundle getBundle() { - return bundle; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/BundlesView.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/BundlesView.java deleted file mode 100644 index 3894810f6..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/BundlesView.java +++ /dev/null @@ -1,147 +0,0 @@ -//package org.argeo.eclipse.ui.workbench.osgi; -//public class BundlesView {} - -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.osgi; - -import java.util.Comparator; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.ColumnViewerComparator; -import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; -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.widgets.Composite; -import org.eclipse.ui.part.ViewPart; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; - -/** - * Overview of the bundles as a table. Equivalent to Equinox 'ss' console - * command. - */ -public class BundlesView extends ViewPart { - private TableViewer viewer; - - @Override - public void createPartControl(Composite parent) { - viewer = new TableViewer(parent); - viewer.setContentProvider(new BundleContentProvider()); - viewer.getTable().setHeaderVisible(true); - - EclipseUiSpecificUtils.enableToolTipSupport(viewer); - - // ID - TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); - column.getColumn().setWidth(30); - column.getColumn().setText("ID"); - column.getColumn().setAlignment(SWT.RIGHT); - column.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -3122136344359358605L; - - public String getText(Object element) { - return Long.toString(((Bundle) element).getBundleId()); - } - }); - new ColumnViewerComparator(column, new Comparator() { - public int compare(Bundle o1, Bundle o2) { - return (int) (o1.getBundleId() - o2.getBundleId()); - } - }); - - // State - column = new TableViewerColumn(viewer, SWT.NONE); - column.getColumn().setWidth(18); - column.getColumn().setText("State"); - column.setLabelProvider(new StateLabelProvider()); - new ColumnViewerComparator(column, new Comparator() { - public int compare(Bundle o1, Bundle o2) { - return o1.getState() - o2.getState(); - } - }); - - // Symbolic name - column = new TableViewerColumn(viewer, SWT.NONE); - column.getColumn().setWidth(250); - column.getColumn().setText("Symbolic Name"); - column.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -4280840684440451080L; - - public String getText(Object element) { - return ((Bundle) element).getSymbolicName(); - } - }); - new ColumnViewerComparator(column, new Comparator() { - public int compare(Bundle o1, Bundle o2) { - return o1.getSymbolicName().compareTo(o2.getSymbolicName()); - } - }); - - // Version - column = new TableViewerColumn(viewer, SWT.NONE); - column.getColumn().setWidth(150); - column.getColumn().setText("Version"); - column.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = 6871926308708629989L; - - public String getText(Object element) { - Bundle bundle = (org.osgi.framework.Bundle) element; - return bundle.getVersion().toString(); - } - }); - new ColumnViewerComparator(column, new Comparator() { - public int compare(Bundle o1, Bundle o2) { - return o1.getVersion().compareTo(o2.getVersion()); - } - }); - - viewer.setInput(SecurityUiPlugin.getDefault().getBundle() - .getBundleContext()); - - } - - @Override - public void setFocus() { - if (viewer != null) - viewer.getControl().setFocus(); - } - - /** Content provider managing the array of bundles */ - private static class BundleContentProvider implements - IStructuredContentProvider { - private static final long serialVersionUID = -8533792785725875977L; - - public Object[] getElements(Object inputElement) { - if (inputElement instanceof BundleContext) { - BundleContext bc = (BundleContext) inputElement; - return bc.getBundles(); - } - return null; - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/ModulesView.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/ModulesView.java deleted file mode 100644 index dec1b2b14..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/ModulesView.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.osgi; - -import java.util.ArrayList; -import java.util.List; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.TreeParent; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.part.ViewPart; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; - -/** The OSGi runtime from a module perspective. */ -public class ModulesView extends ViewPart { - private TreeViewer viewer; - - @Override - public void createPartControl(Composite parent) { - viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - viewer.setContentProvider(new ModulesContentProvider()); - viewer.setLabelProvider(new ModulesLabelProvider()); - viewer.setInput(SecurityUiPlugin.getDefault().getBundle() - .getBundleContext()); - } - - @Override - public void setFocus() { - viewer.getTree().setFocus(); - } - - private class ModulesContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = 3819934804640641721L; - - public Object[] getElements(Object inputElement) { - return getChildren(inputElement); - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof BundleContext) { - BundleContext bundleContext = (BundleContext) parentElement; - Bundle[] bundles = bundleContext.getBundles(); - - List modules = new ArrayList(); - for (Bundle bundle : bundles) { - if (bundle.getState() == Bundle.ACTIVE) - modules.add(new BundleNode(bundle, true)); - } - return modules.toArray(); - } else if (parentElement instanceof TreeParent) { - return ((TreeParent) parentElement).getChildren(); - } else { - return null; - } - } - - public Object getParent(Object element) { - // TODO Auto-generated method stub - return null; - } - - public boolean hasChildren(Object element) { - if (element instanceof TreeParent) { - return ((TreeParent) element).hasChildren(); - } - return false; - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - } - - private class ModulesLabelProvider extends StateLabelProvider { - private static final long serialVersionUID = 5290046145534824722L; - - @Override - public String getText(Object element) { - if (element instanceof BundleNode) - return element.toString() + " [" - + ((BundleNode) element).getBundle().getBundleId() - + "]"; - return element.toString(); - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/MultiplePackagesView.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/MultiplePackagesView.java deleted file mode 100644 index b6a18c483..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/MultiplePackagesView.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.osgi; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.TreeParent; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.part.ViewPart; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.service.packageadmin.ExportedPackage; -import org.osgi.service.packageadmin.PackageAdmin; - -/** Experimental The OSGi runtime from a module perspective. */ -@SuppressWarnings({ "deprecation", "rawtypes", "unchecked" }) -public class MultiplePackagesView extends ViewPart { - private TreeViewer viewer; - private PackageAdmin packageAdmin; - private Comparator epc = new Comparator() { - public int compare(ExportedPackage o1, ExportedPackage o2) { - if (!o1.getName().equals(o2.getName())) - return o1.getName().compareTo(o2.getName()); - else - return o1.getVersion().compareTo(o2.getVersion()); - } - }; - - @Override - public void createPartControl(Composite parent) { - viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - viewer.setContentProvider(new ModulesContentProvider()); - viewer.setLabelProvider(new LabelProvider()); - viewer.setInput(SecurityUiPlugin.getDefault().getBundle() - .getBundleContext()); - } - - @Override - public void setFocus() { - viewer.getTree().setFocus(); - } - - private class ModulesContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = 3819934804640641721L; - - public Object[] getElements(Object inputElement) { - return getChildren(inputElement); - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof BundleContext) { - BundleContext bundleContext = (BundleContext) parentElement; - Bundle[] bundles = bundleContext.getBundles(); - - // scan packages - ServiceReference paSr = bundleContext - .getServiceReference(PackageAdmin.class.getName()); - // TODO: make a cleaner referencing - packageAdmin = (PackageAdmin) bundleContext.getService(paSr); - - Map> imported = new HashMap>(); - Map> packages = new TreeMap>(); - for (Bundle bundle : bundles) { - processBundle(bundle, imported, packages); - } - - List multiplePackages = new ArrayList(); - for (String packageName : packages.keySet()) { - Set pkgs = packages.get(packageName); - if (pkgs.size() > 1) { - MultiplePackagesNode mpn = new MultiplePackagesNode( - packageName, pkgs); - multiplePackages.add(mpn); - } - } - - return multiplePackages.toArray(); - } else if (parentElement instanceof TreeParent) { - return ((TreeParent) parentElement).getChildren(); - } else { - return null; - } - } - - protected void processBundle(Bundle bundle, - Map> imported, - Map> packages) { - ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle); - if (pkgs == null) - return; - for (ExportedPackage pkg : pkgs) { - if (!packages.containsKey(pkg.getName())) - packages.put(pkg.getName(), new TreeSet( - epc)); - Set expPackages = packages.get(pkg.getName()); - expPackages.add(pkg); - - // imported - for (Bundle b : pkg.getImportingBundles()) { - if (bundle.getBundleId() != b.getBundleId()) { - if (!imported.containsKey(b)) { - imported.put(b, new TreeSet(epc)); - } - Set impPackages = imported.get(b); - impPackages.add(pkg); - } - } - } - } - - public Object getParent(Object element) { - // TODO Auto-generated method stub - return null; - } - - public boolean hasChildren(Object element) { - if (element instanceof TreeParent) { - return ((TreeParent) element).hasChildren(); - } - return false; - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - } - - private class MultiplePackagesNode extends TreeParent { - public MultiplePackagesNode(String packageName, - Set exportedPackages) { - super(packageName); - for (ExportedPackage pkg : exportedPackages) { - addChild(new ExportedPackageNode(pkg)); - } - } - } - - private class ExportedPackageNode extends TreeParent { - public ExportedPackageNode(ExportedPackage exportedPackage) { - super(exportedPackage.getName() + " - " - + exportedPackage.getVersion() + " (" - + exportedPackage.getExportingBundle() + ")"); - for (Bundle bundle : exportedPackage.getImportingBundles()) { - addChild(new BundleNode(bundle, true)); - } - } - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/OsgiExplorerImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/OsgiExplorerImages.java deleted file mode 100644 index 1070c9013..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/OsgiExplorerImages.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.osgi; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.swt.graphics.Image; - -/** Shared icons. */ -public class OsgiExplorerImages { - public final static Image INSTALLED = SecurityUiPlugin.getImageDescriptor( - "icons/installed.gif").createImage(); - public final static Image RESOLVED = SecurityUiPlugin.getImageDescriptor( - "icons/resolved.gif").createImage(); - public final static Image STARTING = SecurityUiPlugin.getImageDescriptor( - "icons/starting.gif").createImage(); - public final static Image ACTIVE = SecurityUiPlugin.getImageDescriptor( - "icons/active.gif").createImage(); - public final static Image SERVICE_PUBLISHED = SecurityUiPlugin - .getImageDescriptor("icons/service_published.gif").createImage(); - public final static Image SERVICE_REFERENCED = SecurityUiPlugin - .getImageDescriptor("icons/service_referenced.gif").createImage(); -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/OsgiExplorerPerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/OsgiExplorerPerspective.java deleted file mode 100644 index 8f7f26206..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/OsgiExplorerPerspective.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.osgi; - -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** OSGi explorer perspective (to be enriched declaratively) */ -public class OsgiExplorerPerspective implements IPerspectiveFactory { - - public void createInitialLayout(IPageLayout layout) { - layout.setEditorAreaVisible(true); - layout.setFixed(false); - - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/ServiceReferenceNode.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/ServiceReferenceNode.java deleted file mode 100644 index 0da5287f3..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/ServiceReferenceNode.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.argeo.eclipse.ui.workbench.osgi; - -import org.argeo.eclipse.ui.TreeParent; -import org.osgi.framework.Bundle; -import org.osgi.framework.ServiceReference; - -/** A tree element representing a {@link ServiceReference} */ -@SuppressWarnings({ "rawtypes" }) -class ServiceReferenceNode extends TreeParent { - private final ServiceReference serviceReference; - private final boolean published; - - public ServiceReferenceNode(ServiceReference serviceReference, - boolean published) { - super(serviceReference.toString()); - this.serviceReference = serviceReference; - this.published = published; - - if (isPublished()) { - Bundle[] usedBundles = serviceReference.getUsingBundles(); - if (usedBundles != null) { - for (Bundle b : usedBundles) { - if (b != null) - addChild(new BundleNode(b)); - } - } - } else { - Bundle provider = serviceReference.getBundle(); - addChild(new BundleNode(provider)); - } - - for (String key : serviceReference.getPropertyKeys()) { - addChild(new TreeParent(key + "=" - + serviceReference.getProperty(key))); - } - - } - - public ServiceReference getServiceReference() { - return serviceReference; - } - - public boolean isPublished() { - return published; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/StateLabelProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/StateLabelProvider.java deleted file mode 100644 index 803a35871..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/osgi/StateLabelProvider.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.argeo.eclipse.ui.workbench.osgi; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.swt.graphics.Image; -import org.osgi.framework.Bundle; -import org.osgi.framework.Constants; - -/** Label provider showing the sate of bundles */ -class StateLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = -7885583135316000733L; - - @Override - public Image getImage(Object element) { - int state; - if (element instanceof Bundle) - state = ((Bundle) element).getState(); - else if (element instanceof BundleNode) - state = ((BundleNode) element).getBundle().getState(); - else if (element instanceof ServiceReferenceNode) - if (((ServiceReferenceNode) element).isPublished()) - return OsgiExplorerImages.SERVICE_PUBLISHED; - else - return OsgiExplorerImages.SERVICE_REFERENCED; - else - return null; - - switch (state) { - case Bundle.UNINSTALLED: - return OsgiExplorerImages.INSTALLED; - case Bundle.INSTALLED: - return OsgiExplorerImages.INSTALLED; - case Bundle.RESOLVED: - return OsgiExplorerImages.RESOLVED; - case Bundle.STARTING: - return OsgiExplorerImages.STARTING; - case Bundle.STOPPING: - return OsgiExplorerImages.STARTING; - case Bundle.ACTIVE: - return OsgiExplorerImages.ACTIVE; - default: - return null; - } - } - - @Override - public String getText(Object element) { - return null; - } - - @Override - public String getToolTipText(Object element) { - Bundle bundle = (Bundle) element; - Integer state = bundle.getState(); - switch (state) { - case Bundle.UNINSTALLED: - return "UNINSTALLED"; - case Bundle.INSTALLED: - return "INSTALLED"; - case Bundle.RESOLVED: - return "RESOLVED"; - case Bundle.STARTING: - String activationPolicy = bundle.getHeaders() - .get(Constants.BUNDLE_ACTIVATIONPOLICY).toString(); - - // .get("Bundle-ActivationPolicy").toString(); - // FIXME constant triggers the compilation failure - if (activationPolicy != null - && activationPolicy.equals(Constants.ACTIVATION_LAZY)) - // && activationPolicy.equals("lazy")) - // FIXME constant triggers the compilation failure - // && activationPolicy.equals(Constants.ACTIVATION_LAZY)) - return "<>"; - return "STARTING"; - case Bundle.STOPPING: - return "STOPPING"; - case Bundle.ACTIVE: - return "ACTIVE"; - default: - return null; - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/PickUpUserDialog.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/PickUpUserDialog.java deleted file mode 100644 index b74af70bc..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/PickUpUserDialog.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.eclipse.ui.workbench.users; - -import java.util.ArrayList; -import java.util.List; - -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.eclipse.ui.workbench.internal.users.UsersUtils; -import org.argeo.osgi.useradmin.LdifName; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.TrayDialog; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.FillLayout; -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.Control; -import org.eclipse.swt.widgets.Shell; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; - -/** Dialog with a user (or group) list to pick up one */ -public class PickUpUserDialog extends TrayDialog { - private static final long serialVersionUID = -1420106871173920369L; - - // Business objects - private final UserAdmin userAdmin; - private User selectedUser; - - // this page widgets and UI objects - private String title; - private LdifUsersTable userTableViewerCmp; - private TableViewer userViewer; - private List columnDefs = new ArrayList(); - - /** - * A dialog to pick up a group or a user, showing a table with default - * columns - */ - public PickUpUserDialog(Shell parentShell, String title, UserAdmin userAdmin) { - super(parentShell); - this.title = title; - this.userAdmin = userAdmin; - - columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_ICON), "", - 24, 24)); - columnDefs.add(new ColumnDefinition( - new UserLP(UserLP.COL_DISPLAY_NAME), "Common Name", 150, 100)); - columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DOMAIN), - "Domain", 100, 120)); - columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DN), - "Distinguished Name", 300, 100)); - } - - /** A dialog to pick up a group or a user */ - public PickUpUserDialog(Shell parentShell, String title, - UserAdmin userAdmin, List columnDefs) { - super(parentShell); - this.title = title; - this.userAdmin = userAdmin; - this.columnDefs = columnDefs; - } - - @Override - protected void okPressed() { - if (getSelected() == null) - MessageDialog.openError(getShell(), "No user chosen", - "Please, choose a user or press Cancel."); - else - super.okPressed(); - } - - protected Control createDialogArea(Composite parent) { - Composite dialogArea = (Composite) super.createDialogArea(parent); - dialogArea.setLayout(new FillLayout()); - - Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS); - bodyCmp.setLayout(new GridLayout()); - - // Create and configure the table - userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL); - - userTableViewerCmp.setColumnDefinitions(columnDefs); - userTableViewerCmp.populateWithStaticFilters(false, false); - GridData gd = EclipseUiUtils.fillAll(); - gd.minimumHeight = 300; - userTableViewerCmp.setLayoutData(gd); - userTableViewerCmp.refresh(); - - // Controllers - userViewer = userTableViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new MyDoubleClickListener()); - userViewer - .addSelectionChangedListener(new MySelectionChangedListener()); - - parent.pack(); - return dialogArea; - } - - public User getSelected() { - if (selectedUser == null) - return null; - else - return selectedUser; - } - - protected void configureShell(Shell shell) { - super.configureShell(shell); - shell.setText(title); - } - - class MyDoubleClickListener implements IDoubleClickListener { - public void doubleClick(DoubleClickEvent evt) { - if (evt.getSelection().isEmpty()) - return; - - Object obj = ((IStructuredSelection) evt.getSelection()) - .getFirstElement(); - if (obj instanceof User) { - selectedUser = (User) obj; - okPressed(); - } - } - } - - class MySelectionChangedListener implements ISelectionChangedListener { - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (event.getSelection().isEmpty()) { - selectedUser = null; - return; - } - Object obj = ((IStructuredSelection) event.getSelection()) - .getFirstElement(); - if (obj instanceof Group) { - selectedUser = (Group) obj; - } - } - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private final String[] knownProps = { LdifName.uid.name(), - LdifName.cn.name(), LdifName.dn.name() }; - - private Button showSystemRoleBtn; - private Button showUserBtn; - - public MyUserTableViewer(Composite parent, int style) { - super(parent, style); - } - - protected void populateStaticFilters(Composite staticFilterCmp) { - staticFilterCmp.setLayout(new GridLayout()); - showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); - showSystemRoleBtn.setText("Show system roles "); - - showUserBtn = new Button(staticFilterCmp, SWT.CHECK); - showUserBtn.setText("Show users "); - - SelectionListener sl = new SelectionAdapter() { - private static final long serialVersionUID = -7033424592697691676L; - - @Override - public void widgetSelected(SelectionEvent e) { - refresh(); - } - }; - - showSystemRoleBtn.addSelectionListener(sl); - showUserBtn.addSelectionListener(sl); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - try { - StringBuilder builder = new StringBuilder(); - - StringBuilder filterBuilder = new StringBuilder(); - if (notNull(filter)) - for (String prop : knownProps) { - filterBuilder.append("("); - filterBuilder.append(prop); - filterBuilder.append("=*"); - filterBuilder.append(filter); - filterBuilder.append("*)"); - } - - String typeStr = "(" + LdifName.objectClass.name() + "=" - + LdifName.groupOfNames.name() + ")"; - if ((showUserBtn.getSelection())) - typeStr = "(|(" + LdifName.objectClass.name() + "=" - + LdifName.inetOrgPerson.name() + ")" + typeStr - + ")"; - - if (!showSystemRoleBtn.getSelection()) - typeStr = "(& " + typeStr + "(!(" + LdifName.dn.name() - + "=*" + UsersUtils.ROLES_BASEDN + ")))"; - - if (filterBuilder.length() > 1) { - builder.append("(&" + typeStr); - builder.append("(|"); - builder.append(filterBuilder.toString()); - builder.append("))"); - } else { - builder.append(typeStr); - } - roles = userAdmin.getRoles(builder.toString()); - } catch (InvalidSyntaxException e) { - throw new EclipseUiException("Unable to get roles with filter: " - + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - if (!users.contains(role)) - users.add((User) role); - return users; - } - } - - private boolean notNull(String string) { - if (string == null) - return false; - else - return !"".equals(string.trim()); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/UserLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/UserLP.java deleted file mode 100644 index 0340f8dfe..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/UserLP.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.argeo.eclipse.ui.workbench.users; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.workbench.internal.users.UsersImages; -import org.argeo.eclipse.ui.workbench.internal.users.UsersUtils; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; - -/** Centralize label providers for the group table */ -class UserLP extends ColumnLabelProvider { - private static final long serialVersionUID = -4645930210988368571L; - - final static String COL_ICON = "colID.icon"; - final static String COL_DN = "colID.dn"; - final static String COL_DISPLAY_NAME = "colID.displayName"; - final static String COL_DOMAIN = "colID.domain"; - - final String currType; - - // private Font italic; - private Font bold; - - UserLP(String colId) { - this.currType = colId; - } - - @Override - public Font getFont(Object element) { - // Self as bold - try { - LdapName selfUserName = UsersUtils.getLdapName(); - String userName = ((User) element).getName(); - LdapName userLdapName = new LdapName(userName); - if (userLdapName.equals(selfUserName)) { - if (bold == null) - bold = JFaceResources.getFontRegistry() - .defaultFontDescriptor().setStyle(SWT.BOLD) - .createFont(Display.getCurrent()); - return bold; - } - } catch (InvalidNameException e) { - throw new EclipseUiException("cannot parse dn for " + element, e); - } - - // Disabled as Italic - // Node userProfile = (Node) elem; - // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) - // return italic; - - return null; - // return super.getFont(element); - } - - @Override - public Image getImage(Object element) { - if (COL_ICON.equals(currType)) { - User user = (User) element; - String dn = user.getName(); - if (dn.endsWith(UsersUtils.ROLES_BASEDN)) - return UsersImages.ICON_ROLE; - else if (user.getType() == Role.GROUP) - return UsersImages.ICON_GROUP; - else - return UsersImages.ICON_USER; - } else - return null; - } - - @Override - public String getText(Object element) { - User user = (User) element; - return getText(user); - - } - - public String getText(User user) { - if (COL_DN.equals(currType)) - return user.getName(); - else if (COL_DISPLAY_NAME.equals(currType)) - return UsersUtils.getCommonName(user); - else if (COL_DOMAIN.equals(currType)) - return UsersUtils.getDomainName(user); - else - return ""; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/MaintenancePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/MaintenancePerspective.java deleted file mode 100644 index 5a1ff66fe..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/MaintenancePerspective.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.security.ui.views.AdminLogView; -import org.argeo.security.ui.views.UserProfile; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** Home perspective for the current user */ -public class MaintenancePerspective implements IPerspectiveFactory { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".adminMaintenancePerspective"; - - public void createInitialLayout(IPageLayout layout) { - String editorArea = layout.getEditorArea(); - layout.setEditorAreaVisible(true); - layout.setFixed(false); - - IFolderLayout bottom = layout.createFolder("bottom", - IPageLayout.BOTTOM, 0.50f, editorArea); - bottom.addView(AdminLogView.ID); - - IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, - 0.30f, editorArea); - left.addView(UserProfile.ID); - // left.addView(RolesView.ID); - - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/PrivilegedJob.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/PrivilegedJob.java deleted file mode 100644 index 3a9ade427..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/PrivilegedJob.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.argeo.security.ui; - -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import javax.security.auth.Subject; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.jobs.Job; - -/** - * Propagate authentication to an eclipse job. Typically to execute a privileged - * action outside the UI thread - */ -public abstract class PrivilegedJob extends Job { - private final Subject subject; - - public PrivilegedJob(String jobName) { - this(jobName, AccessController.getContext()); - } - - public PrivilegedJob(String jobName, - AccessControlContext accessControlContext) { - super(jobName); - subject = Subject.getSubject(accessControlContext); - - // Must be called *before* the job is scheduled, - // it is required for the progress window to appear - setUser(true); - } - - @Override - protected IStatus run(final IProgressMonitor progressMonitor) { - PrivilegedAction privilegedAction = new PrivilegedAction() { - public IStatus run() { - return doRun(progressMonitor); - } - }; - return Subject.doAs(subject, privilegedAction); - } - - /** - * Implement here what should be executed with default context - * authentication - */ - protected abstract IStatus doRun(IProgressMonitor progressMonitor); -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/RolesSourceProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/RolesSourceProvider.java deleted file mode 100644 index 42e6f10e7..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/RolesSourceProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.argeo.cms.auth.CurrentUser; -import org.eclipse.ui.AbstractSourceProvider; - -/** - * Provides the roles of the current user as a variable to be used for activity - * binding - */ -public class RolesSourceProvider extends AbstractSourceProvider { - public final static String ROLES_VARIABLE = "roles"; - private final static String[] PROVIDED_SOURCE_NAMES = new String[] { ROLES_VARIABLE }; - - public Map> getCurrentState() { - Map> stateMap = new HashMap>(); - stateMap.put(ROLES_VARIABLE, CurrentUser.roles()); - return stateMap; - } - - public String[] getProvidedSourceNames() { - return PROVIDED_SOURCE_NAMES; - } - - public void updateRoles() { - fireSourceChanged(0, getCurrentState()); - } - - public void dispose() { - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/UserHomePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/UserHomePerspective.java deleted file mode 100644 index 9f4ee1066..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/UserHomePerspective.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.security.ui.views.LogView; -import org.argeo.security.ui.views.UserProfile; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** Home perspective for the current user */ -public class UserHomePerspective implements IPerspectiveFactory { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".userHomePerspective"; - - public void createInitialLayout(IPageLayout layout) { - String editorArea = layout.getEditorArea(); - layout.setEditorAreaVisible(true); - layout.setFixed(false); - - IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, - 0.30f, editorArea); - left.addView(UserProfile.ID); - left.addView(LogView.ID); - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminImages.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminImages.java deleted file mode 100644 index e2bb69920..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminImages.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Argeo Connect - Data management and communications - * Copyright (C) 2012 Argeo GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * - * Additional permission under GNU GPL version 3 section 7 - * - * If you modify this Program, or any covered work, by linking or combining it - * with software covered by the terms of the Eclipse Public License, the - * licensors of this Program grant you additional permission to convey the - * resulting work. Corresponding Source for a non-source form of such a - * combination shall include the source code for the parts of such software - * which are used as well as that of the covered work. - */ -package org.argeo.security.ui.admin; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; - -/** Shared icons that must be declared programmatically . */ -public class SecurityAdminImages { - private final static String PREFIX = "icons/"; - - public final static ImageDescriptor ICON_REMOVE_DESC = SecurityUiPlugin - .getImageDescriptor(PREFIX + "remove.gif"); - public final static ImageDescriptor ICON_USER_DESC = SecurityUiPlugin - .getImageDescriptor(PREFIX + "user.gif"); - - public final static Image ICON_USER = ICON_USER_DESC.createImage(); - public final static Image ICON_GROUP = SecurityUiPlugin.getImageDescriptor( - PREFIX + "users.gif").createImage(); - public final static Image ICON_ROLE = SecurityUiPlugin.getImageDescriptor( - PREFIX + "role.gif").createImage(); - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java deleted file mode 100644 index 2334827c9..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin; - -import org.argeo.security.ui.admin.internal.parts.GroupsView; -import org.argeo.security.ui.admin.internal.parts.UsersView; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** Default perspective to manage users and groups */ -public class SecurityAdminPerspective implements IPerspectiveFactory { - public void createInitialLayout(IPageLayout layout) { - String editorArea = layout.getEditorArea(); - layout.setEditorAreaVisible(true); - layout.setFixed(false); - - IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, - 0.25f, editorArea); - left.addView(UsersView.ID); - left.addView(GroupsView.ID); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminPlugin.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminPlugin.java deleted file mode 100644 index 7222f9234..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/SecurityAdminPlugin.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin; - -public class SecurityAdminPlugin{} - -// public class SecurityAdminPlugin extends AbstractUIPlugin { -// public static final String PLUGIN_ID = "org.argeo.security.ui.admin"; //$NON-NLS-1$ -// private static SecurityAdminPlugin plugin; -// private static BundleContext bundleContext; -// -// public SecurityAdminPlugin() { -// } -// -// public void start(BundleContext context) throws Exception { -// super.start(context); -// plugin = this; -// bundleContext = context; -// } -// -// public void stop(BundleContext context) throws Exception { -// plugin = null; -// bundleContext = null; -// super.stop(context); -// } -// -// public static SecurityAdminPlugin getDefault() { -// return plugin; -// } -// -// public static BundleContext getBundleContext() { -// return bundleContext; -// } -// -// public static ImageDescriptor getImageDescriptor(String path) { -// return imageDescriptorFromPlugin(PLUGIN_ID, path); -// } -// -// } diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/PartStateChanged.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/PartStateChanged.java deleted file mode 100644 index aacf6ef63..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/PartStateChanged.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.argeo.security.ui.admin.internal; - -import org.argeo.cms.CmsException; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IStartup; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PlatformUI; - -/** Manage transaction and part refresh while updating the security model */ -public class PartStateChanged implements IPartListener, IStartup { - // private final static Log log = LogFactory.getLog(PartStateChanged.class); - // private IContextActivation contextActivation; - - @Override - public void earlyStartup() { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - try { - IWorkbenchPage iwp = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage(); - if (iwp != null) - iwp.addPartListener(new PartStateChanged()); - } catch (Exception e) { - throw new CmsException( - "Error while registering the PartStateChangedListener", - e); - } - } - }); - } - - @Override - public void partActivated(IWorkbenchPart part) { - // Nothing to do - } - - @Override - public void partBroughtToTop(IWorkbenchPart part) { - // Nothing to do - } - - @Override - public void partClosed(IWorkbenchPart part) { - // Nothing to do - } - - @Override - public void partDeactivated(IWorkbenchPart part) { - // Nothing to do - } - - @Override - public void partOpened(IWorkbenchPart part) { - // Nothing to do - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java deleted file mode 100644 index 871877a0e..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.argeo.security.ui.admin.internal; - -import javax.transaction.UserTransaction; - -import org.argeo.cms.CmsException; -import org.argeo.security.ui.admin.internal.providers.UserTransactionProvider; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.services.ISourceProviderService; - -/** First effort to centralize back end methods used by the user admin UI */ -public class UiAdminUtils { - /* - * INTERNAL METHODS: Below methods are meant to stay here and are not part - * of a potential generic backend to manage the useradmin - */ - /** Easily notify the ActiveWindow that the transaction had a state change */ - public final static void notifyTransactionStateChange( - UserTransaction userTransaction) { - try { - IWorkbenchWindow aww = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - ISourceProviderService sourceProviderService = (ISourceProviderService) aww - .getService(ISourceProviderService.class); - UserTransactionProvider esp = (UserTransactionProvider) sourceProviderService - .getSourceProvider(UserTransactionProvider.TRANSACTION_STATE); - esp.fireTransactionStateChange(); - } catch (Exception e) { - throw new CmsException("Unable to begin transaction", e); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UiUserAdminListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UiUserAdminListener.java deleted file mode 100644 index 98c983683..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UiUserAdminListener.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.argeo.security.ui.admin.internal; - -import org.eclipse.swt.widgets.Display; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** Convenience class to insure the call to refresh is done in the UI thread */ -public abstract class UiUserAdminListener implements UserAdminListener { - - private final Display display; - - public UiUserAdminListener(Display display) { - this.display = display; - } - - @Override - public void roleChanged(final UserAdminEvent event) { - display.asyncExec(new Runnable() { - @Override - public void run() { - roleChangedToUiThread(event); - } - }); - } - - public abstract void roleChangedToUiThread(UserAdminEvent event); -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java deleted file mode 100644 index d443a3d47..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.argeo.security.ui.admin.internal; - -import java.util.ArrayList; -import java.util.List; - -import javax.transaction.Status; -import javax.transaction.UserTransaction; - -import org.argeo.cms.CmsException; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** Centralise interaction with the UserAdmin in this bundle */ -public class UserAdminWrapper extends - org.argeo.cms.util.useradmin.UserAdminWrapper { - - // First effort to simplify UX while managing users and groups - public final static boolean COMMIT_ON_SAVE = true; - - // Registered listeners - List listeners = new ArrayList(); - - /** - * Starts a transaction if necessary. Should always been called together - * with {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once - * the security model changes have been performed. - */ - public UserTransaction beginTransactionIfNeeded() { - try { - UserTransaction userTransaction = getUserTransaction(); - if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) { - userTransaction.begin(); - // UiAdminUtils.notifyTransactionStateChange(userTransaction); - } - return userTransaction; - } catch (Exception e) { - throw new CmsException("Unable to begin transaction", e); - } - } - - /** - * Depending on the current application configuration, it will either commit - * the current transaction or throw a notification that the transaction - * state has changed (In the later case, it must be called from the UI - * thread). - */ - public void commitOrNotifyTransactionStateChange() { - try { - UserTransaction userTransaction = getUserTransaction(); - if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) - return; - - if (UserAdminWrapper.COMMIT_ON_SAVE) - userTransaction.commit(); - else - UiAdminUtils.notifyTransactionStateChange(userTransaction); - } catch (Exception e) { - throw new CmsException("Unable to clean transaction", e); - } - } - - // TODO implement safer mechanism - public void addListener(UserAdminListener userAdminListener) { - if (!listeners.contains(userAdminListener)) - listeners.add(userAdminListener); - } - - public void removeListener(UserAdminListener userAdminListener) { - if (listeners.contains(userAdminListener)) - listeners.remove(userAdminListener); - } - - public void notifyListeners(UserAdminEvent event) { - for (UserAdminListener listener : listeners) - listener.roleChanged(event); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java deleted file mode 100644 index ff6ff038d..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.parts.UserEditorInput; -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.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.handlers.HandlerUtil; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Delete the selected groups */ -public class DeleteGroups extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".deleteGroups"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - @SuppressWarnings("unchecked") - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (selection.isEmpty()) - return null; - - List groups = new ArrayList(); - Iterator it = ((IStructuredSelection) selection).iterator(); - StringBuilder builder = new StringBuilder(); - while (it.hasNext()) { - Group currGroup = it.next(); - String groupName = UserAdminUtils.getUsername(currGroup); - // TODO add checks - builder.append(groupName).append("; "); - groups.add(currGroup); - } - - if (!MessageDialog.openQuestion(HandlerUtil.getActiveShell(event), - "Delete Groups", - "Are you sure that you " + "want to delete these groups?\n" - + builder.substring(0, builder.length() - 2))) - return null; - - userAdminWrapper.beginTransactionIfNeeded(); - UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); - IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage(); - for (Group group : groups) { - String groupName = group.getName(); - // TODO find a way to close the editor cleanly if opened. Cannot be - // done through the UserAdminListeners, it causes a - // java.util.ConcurrentModificationException because disposing the - // editor unregisters and disposes the listener - IEditorPart part = iwp.findEditor(new UserEditorInput(groupName)); - if (part != null) - iwp.closeEditor(part, false); - userAdmin.removeRole(groupName); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - - // Update the view - for (Group group : groups) { - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_REMOVED, group)); - } - - return null; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java deleted file mode 100644 index cb2fcb071..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.parts.UserEditorInput; -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.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.handlers.HandlerUtil; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Delete the selected users */ -public class DeleteUsers extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".deleteUsers"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - @SuppressWarnings("unchecked") - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (selection.isEmpty()) - return null; - - Iterator it = ((IStructuredSelection) selection).iterator(); - List users = new ArrayList(); - StringBuilder builder = new StringBuilder(); - - while (it.hasNext()) { - User currUser = it.next(); - String userName = UserAdminUtils.getUsername(currUser); - if (UserAdminUtils.isCurrentUser(currUser)) { - MessageDialog.openError(HandlerUtil.getActiveShell(event), - "Deletion forbidden", - "You cannot delete your own user this way."); - return null; - } - builder.append(userName).append("; "); - users.add(currUser); - } - - if (!MessageDialog.openQuestion( - HandlerUtil.getActiveShell(event), - "Delete Users", - "Are you sure that you want to delete these users?\n" - + builder.substring(0, builder.length() - 2))) - return null; - - userAdminWrapper.beginTransactionIfNeeded(); - UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); - IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage(); - - for (User user : users) { - String userName = user.getName(); - // TODO find a way to close the editor cleanly if opened. Cannot be - // done through the UserAdminListeners, it causes a - // java.util.ConcurrentModificationException because disposing the - // editor unregisters and disposes the listener - IEditorPart part = iwp.findEditor(new UserEditorInput(userName)); - if (part != null) - iwp.closeEditor(part, false); - userAdmin.removeRole(userName); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - - for (User user : users) { - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_REMOVED, user)); - } - return null; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/ForceRefresh.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/ForceRefresh.java deleted file mode 100644 index 231c8718a..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/ForceRefresh.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import org.argeo.security.ui.admin.internal.parts.GroupsView; -import org.argeo.security.ui.admin.internal.parts.UsersView; -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.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Retrieve the active view or editor and call forceRefresh method if defined */ -public class ForceRefresh extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow iww = HandlerUtil.getActiveWorkbenchWindow(event); - if (iww == null) - return null; - IWorkbenchPage activePage = iww.getActivePage(); - IWorkbenchPart part = activePage.getActivePart(); - if (part instanceof UsersView) - ((UsersView) part).refresh(); - else if (part instanceof GroupsView) - ((GroupsView) part).refresh(); - return null; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java deleted file mode 100644 index e3abbbc43..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import java.util.Dictionary; -import java.util.Map; - -import org.argeo.cms.CmsException; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.osgi.useradmin.UserAdminConf; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.handlers.HandlerUtil; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Create a new group */ -public class NewGroup extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".newGroup"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - public Object execute(ExecutionEvent event) throws ExecutionException { - NewGroupWizard newGroupWizard = new NewGroupWizard(); - newGroupWizard.setWindowTitle("Group creation"); - WizardDialog dialog = new WizardDialog( - HandlerUtil.getActiveShell(event), newGroupWizard); - dialog.open(); - return null; - } - - private class NewGroupWizard extends Wizard { - - // Pages - private MainGroupInfoWizardPage mainGroupInfo; - - // UI fields - private Text dNameTxt, commonNameTxt, descriptionTxt; - private Combo baseDnCmb; - - public NewGroupWizard() { - } - - @Override - public void addPages() { - mainGroupInfo = new MainGroupInfoWizardPage(); - addPage(mainGroupInfo); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - String commonName = commonNameTxt.getText(); - try { - userAdminWrapper.beginTransactionIfNeeded(); - String dn = getDn(commonName); - Group group = (Group) userAdminWrapper.getUserAdmin() - .createRole(dn, Role.GROUP); - Dictionary props = group.getProperties(); - String descStr = descriptionTxt.getText(); - if (EclipseUiUtils.notEmpty(descStr)) - props.put(LdifName.description.name(), descStr); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CREATED, group)); - return true; - } catch (Exception e) { - ErrorFeedback.show("Cannot create new group " + commonName, e); - return false; - } - } - - private class MainGroupInfoWizardPage extends WizardPage implements - FocusListener, ArgeoNames { - private static final long serialVersionUID = -3150193365151601807L; - - public MainGroupInfoWizardPage() { - super("Main"); - setTitle("General information"); - setMessage("Please choose a domain, provide a common name " - + "and a free description"); - } - - @Override - public void createControl(Composite parent) { - Composite bodyCmp = new Composite(parent, SWT.NONE); - setControl(bodyCmp); - bodyCmp.setLayout(new GridLayout(2, false)); - - dNameTxt = EclipseUiUtils.createGridLT(bodyCmp, - "Distinguished name"); - dNameTxt.setEnabled(false); - - baseDnCmb = createGridLC(bodyCmp, "Base DN"); - // Initialise before adding the listener to avoid NPE - initialiseDnCmb(baseDnCmb); - baseDnCmb.addFocusListener(this); - - commonNameTxt = EclipseUiUtils.createGridLT(bodyCmp, - "Common name"); - commonNameTxt.addFocusListener(this); - - Label descLbl = new Label(bodyCmp, SWT.LEAD); - descLbl.setText("Description"); - descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, - false)); - descriptionTxt = new Text(bodyCmp, SWT.LEAD | SWT.MULTI - | SWT.WRAP | SWT.BORDER); - descriptionTxt.setLayoutData(EclipseUiUtils.fillAll()); - descriptionTxt.addFocusListener(this); - - // Initialize buttons - setPageComplete(false); - getContainer().updateButtons(); - } - - @Override - public void focusLost(FocusEvent event) { - String name = commonNameTxt.getText(); - if (EclipseUiUtils.isEmpty(name)) - dNameTxt.setText(""); - else - dNameTxt.setText(getDn(name)); - - String message = checkComplete(); - if (message != null) { - setMessage(message, WizardPage.ERROR); - setPageComplete(false); - } else { - setMessage("Complete", WizardPage.INFORMATION); - setPageComplete(true); - } - getContainer().updateButtons(); - } - - @Override - public void focusGained(FocusEvent event) { - } - - /** @return the error message or null if complete */ - protected String checkComplete() { - String name = commonNameTxt.getText(); - - if (name.trim().equals("")) - return "Common name must not be empty"; - Role role = userAdminWrapper.getUserAdmin() - .getRole(getDn(name)); - if (role != null) - return "Group " + name + " already exists"; - return null; - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) - if (baseDnCmb.getSelectionIndex() == -1) - baseDnCmb.setFocus(); - else - commonNameTxt.setFocus(); - } - } - - private Map getDns() { - return userAdminWrapper.getKnownBaseDns(true); - } - - private String getDn(String cn) { - Map dns = getDns(); - String bdn = baseDnCmb.getText(); - if (EclipseUiUtils.notEmpty(bdn)) { - Dictionary props = UserAdminConf.uriAsProperties(dns - .get(bdn)); - String dn = LdifName.cn.name() + "=" + cn + "," - + UserAdminConf.groupBase.getValue(props) + "," + bdn; - return dn; - } - return null; - } - - private void initialiseDnCmb(Combo combo) { - Map dns = userAdminWrapper.getKnownBaseDns(true); - if (dns.isEmpty()) - throw new CmsException( - "No writable base dn found. Cannot create group"); - combo.setItems(dns.keySet().toArray(new String[0])); - if (dns.size() == 1) - combo.select(0); - } - } - - private Combo createGridLC(Composite parent, String label) { - Label lbl = new Label(parent, SWT.LEAD); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY); - combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return combo; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/NewUser.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/NewUser.java deleted file mode 100644 index a7ec2d9b3..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/NewUser.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import java.util.Dictionary; -import java.util.List; -import java.util.Map; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.argeo.cms.CmsException; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.osgi.useradmin.UserAdminConf; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.handlers.HandlerUtil; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Open a wizard that enables creation of a new user. */ -public class NewUser extends AbstractHandler { - /** - * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}. - * Thanks to this tip. - */ - public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; - // private final static Log log = LogFactory.getLog(NewUser.class); - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".newUser"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - public Object execute(ExecutionEvent event) throws ExecutionException { - NewUserWizard newUserWizard = new NewUserWizard(); - newUserWizard.setWindowTitle("User creation"); - WizardDialog dialog = new WizardDialog( - HandlerUtil.getActiveShell(event), newUserWizard); - dialog.open(); - return null; - } - - private class NewUserWizard extends Wizard { - - // pages - private MainUserInfoWizardPage mainUserInfo; - - // End user fields - private Text dNameTxt, usernameTxt, firstNameTxt, lastNameTxt, - primaryMailTxt, pwd1Txt, pwd2Txt; - private Combo baseDnCmb; - - public NewUserWizard() { - - } - - @Override - public void addPages() { - mainUserInfo = new MainUserInfoWizardPage(); - addPage(mainUserInfo); - String message = "Default wizard that also eases user creation tests:\n " - + "Mail and last name are automatically " - + "generated form the uid. Password are defauted to 'demo'."; - mainUserInfo.setMessage(message, WizardPage.WARNING); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - String username = mainUserInfo.getUsername(); - userAdminWrapper.beginTransactionIfNeeded(); - try { - User user = (User) userAdminWrapper.getUserAdmin().createRole( - getDn(username), Role.USER); - - Dictionary props = user.getProperties(); - - String lastNameStr = lastNameTxt.getText(); - if (EclipseUiUtils.notEmpty(lastNameStr)) - props.put(LdifName.sn.name(), lastNameStr); - - String firstNameStr = firstNameTxt.getText(); - if (EclipseUiUtils.notEmpty(firstNameStr)) - props.put(LdifName.givenName.name(), firstNameStr); - - String cn = UserAdminUtils.buildDefaultCn(firstNameStr, - lastNameStr); - if (EclipseUiUtils.notEmpty(cn)) - props.put(LdifName.cn.name(), cn); - - String mailStr = primaryMailTxt.getText(); - if (EclipseUiUtils.notEmpty(mailStr)) - props.put(LdifName.mail.name(), mailStr); - - char[] password = mainUserInfo.getPassword(); - user.getCredentials().put(null, password); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CREATED, user)); - return true; - } catch (Exception e) { - ErrorFeedback.show("Cannot create new user " + username, e); - return false; - } - } - - private class MainUserInfoWizardPage extends WizardPage implements - ModifyListener, ArgeoNames { - private static final long serialVersionUID = -3150193365151601807L; - - public MainUserInfoWizardPage() { - super("Main"); - setTitle("Required Information"); - } - - @Override - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - dNameTxt = EclipseUiUtils.createGridLT(composite, - "Distinguished name", this); - dNameTxt.setEnabled(false); - - baseDnCmb = createGridLC(composite, "Base DN"); - initialiseDnCmb(baseDnCmb); - baseDnCmb.addModifyListener(this); - baseDnCmb.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = -1435351236582736843L; - - @Override - public void modifyText(ModifyEvent event) { - String name = usernameTxt.getText(); - dNameTxt.setText(getDn(name)); - } - }); - - usernameTxt = EclipseUiUtils.createGridLT(composite, - "Local ID", this); - usernameTxt.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = -1435351236582736843L; - - @Override - public void modifyText(ModifyEvent event) { - String name = usernameTxt.getText(); - if (name.trim().equals("")) { - dNameTxt.setText(""); - lastNameTxt.setText(""); - primaryMailTxt.setText(""); - pwd1Txt.setText(""); - pwd2Txt.setText(""); - } else { - dNameTxt.setText(getDn(name)); - lastNameTxt.setText(name.toUpperCase()); - primaryMailTxt.setText(getMail(name)); - pwd1Txt.setText("demo"); - pwd2Txt.setText("demo"); - } - } - }); - - primaryMailTxt = EclipseUiUtils.createGridLT(composite, - "Email", this); - firstNameTxt = EclipseUiUtils.createGridLT(composite, - "First name", this); - lastNameTxt = EclipseUiUtils.createGridLT(composite, - "Last name", this); - pwd1Txt = EclipseUiUtils.createGridLP(composite, "Password", - this); - pwd2Txt = EclipseUiUtils.createGridLP(composite, - "Repeat password", this); - setControl(composite); - - // Initialize buttons - setPageComplete(false); - getContainer().updateButtons(); - } - - @Override - public void modifyText(ModifyEvent event) { - String message = checkComplete(); - if (message != null) { - setMessage(message, WizardPage.ERROR); - setPageComplete(false); - } else { - setMessage("Complete", WizardPage.INFORMATION); - setPageComplete(true); - } - getContainer().updateButtons(); - } - - /** @return error message or null if complete */ - protected String checkComplete() { - String name = usernameTxt.getText(); - - if (name.trim().equals("")) - return "User name must not be empty"; - Role role = userAdminWrapper.getUserAdmin() - .getRole(getDn(name)); - if (role != null) - return "User " + name + " already exists"; - if (!primaryMailTxt.getText().matches(EMAIL_PATTERN)) - return "Not a valid email address"; - if (lastNameTxt.getText().trim().equals("")) - return "Specify a last name"; - if (pwd1Txt.getText().trim().equals("")) - return "Specify a password"; - if (pwd2Txt.getText().trim().equals("")) - return "Repeat the password"; - if (!pwd2Txt.getText().equals(pwd1Txt.getText())) - return "Passwords are different"; - return null; - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) - if (baseDnCmb.getSelectionIndex() == -1) - baseDnCmb.setFocus(); - else - usernameTxt.setFocus(); - } - - public String getUsername() { - return usernameTxt.getText(); - } - - public char[] getPassword() { - return pwd1Txt.getTextChars(); - } - - } - - private Map getDns() { - return userAdminWrapper.getKnownBaseDns(true); - } - - private String getDn(String uid) { - Map dns = getDns(); - String bdn = baseDnCmb.getText(); - if (EclipseUiUtils.notEmpty(bdn)) { - Dictionary props = UserAdminConf.uriAsProperties(dns - .get(bdn)); - String dn = LdifName.uid.name() + "=" + uid + "," - + UserAdminConf.userBase.getValue(props) + "," + bdn; - return dn; - } - return null; - } - - private void initialiseDnCmb(Combo combo) { - Map dns = userAdminWrapper.getKnownBaseDns(true); - if (dns.isEmpty()) - throw new CmsException( - "No writable base dn found. Cannot create user"); - combo.setItems(dns.keySet().toArray(new String[0])); - if (dns.size() == 1) - combo.select(0); - } - - private String getMail(String username) { - if (baseDnCmb.getSelectionIndex() == -1) - return null; - String baseDn = baseDnCmb.getText(); - try { - LdapName name = new LdapName(baseDn); - List rdns = name.getRdns(); - return username + "@" + (String) rdns.get(1).getValue() + '.' - + (String) rdns.get(0).getValue(); - } catch (InvalidNameException e) { - throw new CmsException("Unable to generate mail for " - + username + " with base dn " + baseDn, e); - } - } - } - - private Combo createGridLC(Composite parent, String label) { - Label lbl = new Label(parent, SWT.LEAD); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY); - combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return combo; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/SaveArgeoUser.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/SaveArgeoUser.java deleted file mode 100644 index b5b394c3d..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/SaveArgeoUser.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -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.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Save the currently edited Argeo user. */ -public class SaveArgeoUser extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".saveArgeoUser"; - - public Object execute(ExecutionEvent event) throws ExecutionException { - try { - IWorkbenchPart iwp = HandlerUtil.getActiveWorkbenchWindow(event) - .getActivePage().getActivePart(); - if (!(iwp instanceof IEditorPart)) - return null; - IEditorPart editor = (IEditorPart) iwp; - editor.doSave(null); - } catch (Exception e) { - MessageDialog.openError(Display.getDefault().getActiveShell(), - "Error", "Cannot save user: " + e.getMessage()); - } - return null; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/UserBatchUpdate.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/UserBatchUpdate.java deleted file mode 100644 index c02f5c220..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/UserBatchUpdate.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.parts.UserBatchUpdateWizard; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Launch a wizard to perform batch process on users */ -public class UserBatchUpdate extends AbstractHandler { - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper uaWrapper; - - public Object execute(ExecutionEvent event) throws ExecutionException { - UserBatchUpdateWizard wizard = new UserBatchUpdateWizard(uaWrapper); - wizard.setWindowTitle("User batch processing"); - WizardDialog dialog = new WizardDialog( - HandlerUtil.getActiveShell(event), wizard); - dialog.open(); - return null; - } - - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.uaWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/UserTransactionHandler.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/UserTransactionHandler.java deleted file mode 100644 index 85e44c1b3..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/commands/UserTransactionHandler.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.commands; - -import javax.transaction.Status; -import javax.transaction.UserTransaction; - -import org.argeo.cms.CmsException; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.security.ui.admin.internal.UiAdminUtils; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Manage the transaction that is bound to the current perspective */ -public class UserTransactionHandler extends AbstractHandler { - public final static String ID = SecurityUiPlugin.PLUGIN_ID - + ".userTransactionHandler"; - - public final static String PARAM_COMMAND_ID = "param.commandId"; - - public final static String TRANSACTION_BEGIN = "transaction.begin"; - public final static String TRANSACTION_COMMIT = "transaction.commit"; - public final static String TRANSACTION_ROLLBACK = "transaction.rollback"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - public Object execute(ExecutionEvent event) throws ExecutionException { - String commandId = event.getParameter(PARAM_COMMAND_ID); - final UserTransaction userTransaction = userAdminWrapper - .getUserTransaction(); - try { - if (TRANSACTION_BEGIN.equals(commandId)) { - if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION) - throw new CmsException("A transaction already exists"); - else - userTransaction.begin(); - } else if (TRANSACTION_COMMIT.equals(commandId)) { - if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) - throw new CmsException("No transaction."); - else - userTransaction.commit(); - } else if (TRANSACTION_ROLLBACK.equals(commandId)) { - if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) - throw new CmsException("No transaction to rollback."); - else { - userTransaction.rollback(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CHANGED, null)); - } - } - - UiAdminUtils.notifyTransactionStateChange(userTransaction); - // Try to remove invalid thread access errors when managing users. - // HandlerUtil.getActivePart(event).getSite().getShell().getDisplay() - // .asyncExec(new Runnable() { - // @Override - // public void run() { - // UiAdminUtils - // .notifyTransactionStateChange(userTransaction); - // } - // }); - - } catch (CmsException e) { - throw e; - } catch (Exception e) { - throw new CmsException("Unable to call " + commandId + " on " - + userTransaction, e); - } - return null; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/ArgeoUserEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/ArgeoUserEditorInput.java deleted file mode 100644 index cca2a1215..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/ArgeoUserEditorInput.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; - -/** Editor input for an Argeo user. */ -public class ArgeoUserEditorInput implements IEditorInput { - private final String username; - - public ArgeoUserEditorInput(String username) { - this.username = username; - } - - public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { - return null; - } - - public boolean exists() { - return username != null; - } - - public ImageDescriptor getImageDescriptor() { - return null; - } - - public String getName() { - return username != null ? username : ""; - } - - public IPersistableElement getPersistable() { - return null; - } - - public String getToolTipText() { - return username != null ? username : ""; - } - - public boolean equals(Object obj) { - if (!(obj instanceof ArgeoUserEditorInput)) - return false; - if (((ArgeoUserEditorInput) obj).getUsername() == null) - return false; - return ((ArgeoUserEditorInput) obj).getUsername().equals(username); - } - - public String getUsername() { - return username; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java deleted file mode 100644 index 3fe07f782..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.Arrays; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.RepositoryException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.node.ArgeoNames; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.AbstractFormPart; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.SectionPart; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; - -/** Display/edit the properties common to all Argeo users */ -public class DefaultUserMainPage extends FormPage implements ArgeoNames { - final static String ID = "argeoUserEditor.mainPage"; - - private final static Log log = LogFactory.getLog(DefaultUserMainPage.class); - private Node userProfile; - - private char[] newPassword; - - public DefaultUserMainPage(FormEditor editor, Node userProfile) { - super(editor, ID, "Main"); - this.userProfile = userProfile; - } - - protected void createFormContent(final IManagedForm mf) { - try { - ScrolledForm form = mf.getForm(); - refreshFormTitle(form); - GridLayout mainLayout = new GridLayout(1, true); - form.getBody().setLayout(mainLayout); - - createGeneralPart(form.getBody()); - createPassworPart(form.getBody()); - } catch (RepositoryException e) { - throw new CmsException("Cannot create form content", e); - } - } - - /** Creates the general section */ - protected void createGeneralPart(Composite parent) - throws RepositoryException { - FormToolkit tk = getManagedForm().getToolkit(); - Section section = tk.createSection(parent, Section.TITLE_BAR); - section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - section.setText("General"); - Composite body = tk.createComposite(section, SWT.WRAP); - section.setClient(body); - GridLayout layout = new GridLayout(2, false); - body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - body.setLayout(layout); - - final Text commonName = createLT(body, "Displayed Name", - getProperty(Property.JCR_TITLE)); - final Text firstName = createLT(body, "First name", - getProperty(ARGEO_FIRST_NAME)); - final Text lastName = createLT(body, "Last name", - getProperty(ARGEO_LAST_NAME)); - final Text email = createLT(body, "Email", - getProperty(ARGEO_PRIMARY_EMAIL)); - final Text description = createLMT(body, "Description", - getProperty(Property.JCR_DESCRIPTION)); - - // create form part (controller) - AbstractFormPart part = new SectionPart(section) { - public void commit(boolean onSave) { - try { - userProfile.getSession().getWorkspace().getVersionManager() - .checkout(userProfile.getPath()); - userProfile.setProperty(Property.JCR_TITLE, - commonName.getText()); - userProfile.setProperty(ARGEO_FIRST_NAME, - firstName.getText()); - userProfile - .setProperty(ARGEO_LAST_NAME, lastName.getText()); - userProfile.setProperty(ARGEO_PRIMARY_EMAIL, - email.getText()); - userProfile.setProperty(Property.JCR_DESCRIPTION, - description.getText()); - userProfile.getSession().save(); - userProfile.getSession().getWorkspace().getVersionManager() - .checkin(userProfile.getPath()); - super.commit(onSave); - refreshFormTitle(getManagedForm().getForm()); - if (log.isTraceEnabled()) - log.trace("General part committed"); - } catch (RepositoryException e) { - throw new CmsException("Cannot commit", e); - } - } - }; - // if (username != null) - // username.addModifyListener(new FormPartML(part)); - commonName.addModifyListener(new FormPartML(part)); - firstName.addModifyListener(new FormPartML(part)); - lastName.addModifyListener(new FormPartML(part)); - email.addModifyListener(new FormPartML(part)); - description.addModifyListener(new FormPartML(part)); - getManagedForm().addPart(part); - } - - private void refreshFormTitle(ScrolledForm form) throws RepositoryException { - form.setText(getProperty(Property.JCR_TITLE) - + (userProfile.getProperty(ARGEO_ENABLED).getBoolean() ? "" - : " [DISABLED]")); - } - - /** @return the property, or the empty string if not set */ - protected String getProperty(String name) throws RepositoryException { - return userProfile.hasProperty(name) ? userProfile.getProperty(name) - .getString() : ""; - } - - /** Creates the password section */ - protected void createPassworPart(Composite parent) { - FormToolkit tk = getManagedForm().getToolkit(); - Section section = tk.createSection(parent, Section.TITLE_BAR); - section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - section.setText("Password"); - - Composite body = tk.createComposite(section, SWT.WRAP); - section.setClient(body); - GridLayout layout = new GridLayout(2, false); - body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - body.setLayout(layout); - - // add widgets (view) - final Text password1 = createLP(body, "New password", ""); - final Text password2 = createLP(body, "Repeat password", ""); - // create form part (controller) - AbstractFormPart part = new SectionPart(section) { - - public void commit(boolean onSave) { - if (!password1.getText().equals("") - || !password2.getText().equals("")) { - if (password1.getText().equals(password2.getText())) { - newPassword = password1.getText().toCharArray(); - password1.setText(""); - password2.setText(""); - super.commit(onSave); - } else { - password1.setText(""); - password2.setText(""); - throw new CmsException("Passwords are not equals"); - } - } - } - - }; - password1.addModifyListener(new FormPartML(part)); - password2.addModifyListener(new FormPartML(part)); - getManagedForm().addPart(part); - } - - /** Creates label and text. */ - protected Text createLT(Composite body, String label, String value) { - FormToolkit toolkit = getManagedForm().getToolkit(); - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return text; - } - - /** Creates label and multiline text. */ - protected Text createLMT(Composite body, String label, String value) { - FormToolkit toolkit = getManagedForm().getToolkit(); - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - return text; - } - - /** Creates label and password. */ - protected Text createLP(Composite body, String label, String value) { - FormToolkit toolkit = getManagedForm().getToolkit(); - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return text; - } - - private class FormPartML implements ModifyListener { - private static final long serialVersionUID = 6299808129505381333L; - private AbstractFormPart formPart; - - public FormPartML(AbstractFormPart generalPart) { - this.formPart = generalPart; - } - - public void modifyText(ModifyEvent e) { - formPart.markDirty(); - } - } - - public String getNewPassword() { - if (newPassword != null) - return new String(newPassword); - else - return null; - } - - public void resetNewPassword() { - if (newPassword != null) - Arrays.fill(newPassword, 'x'); - newPassword = null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java deleted file mode 100644 index b48726f48..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.transaction.UserTransaction; - -import org.argeo.cms.CmsException; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.security.ui.admin.SecurityAdminImages; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.parts.UserEditor.GroupChangeListener; -import org.argeo.security.ui.admin.internal.parts.UserEditor.MainInfoListener; -import org.argeo.security.ui.admin.internal.providers.CommonNameLP; -import org.argeo.security.ui.admin.internal.providers.MailLP; -import org.argeo.security.ui.admin.internal.providers.RoleIconLP; -import org.argeo.security.ui.admin.internal.providers.UserFilter; -import org.argeo.security.ui.admin.internal.providers.UserNameLP; -import org.argeo.security.ui.admin.internal.providers.UserTableDefaultDClickListener; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.ViewerDropAdapter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.ui.forms.AbstractFormPart; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.SectionPart; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Display/edit main properties of a given group */ -public class GroupMainPage extends FormPage implements ArgeoNames { - final static String ID = "GroupEditor.mainPage"; - - private final UserEditor editor; - private UserAdminWrapper userAdminWrapper; - - // Local configuration - private final int PRE_TITLE_INDENT = 10; - - public GroupMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) { - super(editor, ID, "Main"); - this.editor = (UserEditor) editor; - this.userAdminWrapper = userAdminWrapper; - } - - protected void createFormContent(final IManagedForm mf) { - ScrolledForm form = mf.getForm(); - Composite body = form.getBody(); - GridLayout mainLayout = new GridLayout(); - body.setLayout(mainLayout); - Group group = (Group) editor.getDisplayedUser(); - appendOverviewPart(body, group); - appendMembersPart(body, group); - } - - /** Creates the general section */ - protected void appendOverviewPart(final Composite parent, final Group group) { - FormToolkit tk = getManagedForm().getToolkit(); - Composite body = addSection(tk, parent, "Main information"); - GridLayout layout = new GridLayout(2, false); - body.setLayout(layout); - - final Text dnTxt = createLT(body, "DN", group.getName()); - dnTxt.setEnabled(false); - - final Text cnTxt = createLT(body, "Common Name", - UserAdminUtils.getProperty(group, LdifName.cn.name())); - cnTxt.setEnabled(false); - - Label descLbl = new Label(body, SWT.LEAD); - descLbl.setText("Description"); - descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); - final Text descTxt = new Text(body, SWT.LEAD | SWT.MULTI | SWT.WRAP - | SWT.BORDER); - GridData gd = EclipseUiUtils.fillAll(); - gd.heightHint = 100; - descTxt.setLayoutData(gd); - - // create form part (controller) - AbstractFormPart part = new SectionPart((Section) body.getParent()) { - - private MainInfoListener listener; - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = editor.new MainInfoListener(parent.getDisplay(), - this); - userAdminWrapper.addListener(listener); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @SuppressWarnings("unchecked") - public void commit(boolean onSave) { - group.getProperties().put(LdifName.description.name(), - descTxt.getText()); - // Enable common name ? - // editor.setProperty(UserAdminConstants.KEY_CN, - // email.getText()); - super.commit(onSave); - } - - @Override - public void refresh() { - refreshFormTitle(group); - dnTxt.setText(group.getName()); - cnTxt.setText(UserAdminUtils.getProperty(group, - LdifName.cn.name())); - descTxt.setText(UserAdminUtils.getProperty(group, - LdifName.description.name())); - super.refresh(); - } - }; - - ModifyListener defaultListener = editor.new FormPartML(part); - descTxt.addModifyListener(defaultListener); - getManagedForm().addPart(part); - } - - /** Filtered table with members. Has drag & drop ability */ - protected void appendMembersPart(Composite parent, Group group) { - - FormToolkit tk = getManagedForm().getToolkit(); - Section section = tk.createSection(parent, Section.TITLE_BAR); - section.setLayoutData(EclipseUiUtils.fillAll()); - - Composite body = new Composite(section, SWT.NO_FOCUS); - section.setClient(body); - body.setLayoutData(EclipseUiUtils.fillAll()); - - LdifUsersTable userTableViewerCmp = createMemberPart(body, group); - - SectionPart part = new GroupMembersPart(section, userTableViewerCmp, - group); - getManagedForm().addPart(part); - addRemoveAbitily(part, userTableViewerCmp.getTableViewer(), group); - } - - public LdifUsersTable createMemberPart(Composite parent, Group group) { - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - // Define the displayed columns - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", - 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "Primary Mail", 150)); - columnDefs.add(new ColumnDefinition(new UserNameLP(), - "Distinguished Name", 240)); - - // Create and configure the table - LdifUsersTable userViewerCmp = new MyUserTableViewer(parent, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL, userAdminWrapper.getUserAdmin()); - - userViewerCmp.setColumnDefinitions(columnDefs); - userViewerCmp.populate(true, false); - userViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); - - // Controllers - TableViewer userViewer = userViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - userViewer.addDropSupport(operations, tt, - new GroupDropListener(userAdminWrapper, userViewerCmp, - (Group) editor.getDisplayedUser())); - - return userViewerCmp; - } - - // Local viewers - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private final UserFilter userFilter; - - public MyUserTableViewer(Composite parent, int style, - UserAdmin userAdmin) { - super(parent, style, true); - userFilter = new UserFilter(); - - } - - @Override - protected List listFilteredElements(String filter) { - Group group = (Group) editor.getDisplayedUser(); - Role[] roles = group.getMembers(); - List users = new ArrayList(); - userFilter.setSearchText(filter); - for (Role role : roles) - // if (role.getType() == Role.GROUP) - if (userFilter.select(null, null, role)) - users.add((User) role); - return users; - } - } - - private void addRemoveAbitily(SectionPart sectionPart, - TableViewer userViewer, Group group) { - Section section = sectionPart.getSection(); - ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - ToolBar toolbar = toolBarManager.createControl(section); - final Cursor handCursor = new Cursor(section.getDisplay(), - SWT.CURSOR_HAND); - toolbar.setCursor(handCursor); - toolbar.addDisposeListener(new DisposeListener() { - private static final long serialVersionUID = 3882131405820522925L; - - public void widgetDisposed(DisposeEvent e) { - if ((handCursor != null) && (handCursor.isDisposed() == false)) { - handCursor.dispose(); - } - } - }); - - Action action = new RemoveMembershipAction(userViewer, group, - "Remove selected items from this group", - SecurityAdminImages.ICON_REMOVE_DESC); - toolBarManager.add(action); - toolBarManager.update(true); - section.setTextClient(toolbar); - } - - private class RemoveMembershipAction extends Action { - private static final long serialVersionUID = -1337713097184522588L; - - private final TableViewer userViewer; - private final Group group; - - RemoveMembershipAction(TableViewer userViewer, Group group, - String name, ImageDescriptor img) { - super(name, img); - this.userViewer = userViewer; - this.group = group; - } - - @Override - public void run() { - ISelection selection = userViewer.getSelection(); - if (selection.isEmpty()) - return; - - @SuppressWarnings("unchecked") - Iterator it = ((IStructuredSelection) selection).iterator(); - List users = new ArrayList(); - while (it.hasNext()) { - User currUser = it.next(); - users.add(currUser); - } - - userAdminWrapper.beginTransactionIfNeeded(); - for (User user : users) { - group.removeMember(user); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CHANGED, group)); - } - } - - // LOCAL CONTROLLERS - private class GroupMembersPart extends SectionPart { - private final LdifUsersTable userViewer; - private final Group group; - - private GroupChangeListener listener; - - public GroupMembersPart(Section section, LdifUsersTable userViewer, - Group group) { - super(section); - this.userViewer = userViewer; - this.group = group; - } - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = editor.new GroupChangeListener(userViewer.getDisplay(), - GroupMembersPart.this); - userAdminWrapper.addListener(listener); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @Override - public void refresh() { - refreshFormTitle(group); - getSection().setText( - "Members of group " - + UserAdminUtils.getProperty(group, - LdifName.cn.name())); - userViewer.refresh(); - super.refresh(); - } - } - - /** - * Defines this table as being a potential target to add group membership - * (roles) to this group - */ - private class GroupDropListener extends ViewerDropAdapter { - private static final long serialVersionUID = 2893468717831451621L; - - private final UserAdminWrapper userAdminWrapper; - // private final LdifUsersTable myUserViewerCmp; - private final Group myGroup; - - public GroupDropListener(UserAdminWrapper userAdminWrapper, - LdifUsersTable userTableViewerCmp, Group group) { - super(userTableViewerCmp.getTableViewer()); - this.userAdminWrapper = userAdminWrapper; - this.myGroup = group; - // this.myUserViewerCmp = userTableViewerCmp; - } - - @Override - public boolean validateDrop(Object target, int operation, - TransferData transferType) { - // Target is always OK in a list only view - // TODO check if not a string - boolean validDrop = true; - return validDrop; - } - - @Override - public void drop(DropTargetEvent event) { - // TODO Is there an opportunity to perform the check before? - - String newUserName = (String) event.data; - UserAdmin myUserAdmin = userAdminWrapper.getUserAdmin(); - Role role = myUserAdmin.getRole(newUserName); - if (role.getType() == Role.GROUP) { - Group newGroup = (Group) role; - Shell shell = getViewer().getControl().getShell(); - // Sanity checks - if (myGroup == newGroup) { // Equality - MessageDialog.openError(shell, "Forbidden addition ", - "A group cannot be a member of itself."); - return; - } - - // Cycle - String myName = myGroup.getName(); - List myMemberships = editor.getFlatGroups(myGroup); - if (myMemberships.contains(newGroup)) { - MessageDialog.openError(shell, "Forbidden addition: cycle", - "Cannot add " + newUserName + " to group " + myName - + ". This would create a cycle"); - return; - } - - // Already member - List newGroupMemberships = editor.getFlatGroups(newGroup); - if (newGroupMemberships.contains(myGroup)) { - MessageDialog.openError(shell, "Forbidden addition", - "Cannot add " + newUserName + " to group " + myName - + ", this membership already exists"); - return; - } - userAdminWrapper.beginTransactionIfNeeded(); - myGroup.addMember(newGroup); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CHANGED, myGroup)); - } else if (role.getType() == Role.USER) { - // TODO check if the group is already member of this group - UserTransaction transaction = userAdminWrapper - .beginTransactionIfNeeded(); - User user = (User) role; - myGroup.addMember(user); - if (UserAdminWrapper.COMMIT_ON_SAVE) - try { - transaction.commit(); - } catch (Exception e) { - throw new CmsException("Cannot commit transaction " - + "after user group membership update", e); - } - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CHANGED, myGroup)); - } - super.drop(event); - } - - @Override - public boolean performDrop(Object data) { - // myUserViewerCmp.refresh(); - return true; - } - } - - // LOCAL HELPERS - private void refreshFormTitle(Group group) { - getManagedForm().getForm().setText( - UserAdminUtils.getProperty(group, LdifName.cn.name())); - } - - private Composite addSection(FormToolkit tk, Composite parent, String title) { - Section section = tk.createSection(parent, Section.TITLE_BAR); - GridData gd = EclipseUiUtils.fillWidth(); - gd.verticalAlignment = PRE_TITLE_INDENT; - section.setLayoutData(gd); - section.setText(title); - Composite body = tk.createComposite(section, SWT.WRAP); - body.setLayoutData(EclipseUiUtils.fillAll()); - section.setClient(body); - return body; - } - - /** Creates label and text. */ - private Text createLT(Composite body, String label, String value) { - FormToolkit toolkit = getManagedForm().getToolkit(); - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return text; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java deleted file mode 100644 index f7ad517a5..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.cms.auth.AuthConstants; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.security.ui.admin.internal.UiUserAdminListener; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.providers.CommonNameLP; -import org.argeo.security.ui.admin.internal.providers.DomainNameLP; -import org.argeo.security.ui.admin.internal.providers.RoleIconLP; -import org.argeo.security.ui.admin.internal.providers.UserDragListener; -import org.argeo.security.ui.admin.internal.providers.UserNameLP; -import org.argeo.security.ui.admin.internal.providers.UserTableDefaultDClickListener; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.part.ViewPart; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** List all groups with filter */ -public class GroupsView extends ViewPart implements ArgeoNames { - private final static Log log = LogFactory.getLog(GroupsView.class); - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".groupsView"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - // UI Objects - private LdifUsersTable groupTableViewerCmp; - private TableViewer userViewer; - private List columnDefs = new ArrayList(); - - private UserAdminListener listener; - - @Override - public void createPartControl(Composite parent) { - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - boolean isAdmin = UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN); - - // Define the displayed columns - columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 26)); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", - 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); - // Only show technical DN to admin - if (isAdmin) - columnDefs.add(new ColumnDefinition(new UserNameLP(), - "Distinguished Name", 300)); - - // Create and configure the table - groupTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL); - - groupTableViewerCmp.setColumnDefinitions(columnDefs); - if (isAdmin) - groupTableViewerCmp.populateWithStaticFilters(false, false); - else - groupTableViewerCmp.populate(true, false); - - groupTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); - - // Links - userViewer = groupTableViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); - getViewSite().setSelectionProvider(userViewer); - - // Really? - groupTableViewerCmp.refresh(); - - // Drag and drop - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - userViewer.addDragSupport(operations, tt, new UserDragListener( - userViewer)); - - // // Register a useradmin listener - // listener = new UserAdminListener() { - // @Override - // public void roleChanged(UserAdminEvent event) { - // if (userViewer != null && !userViewer.getTable().isDisposed()) - // refresh(); - // } - // }; - // userAdminWrapper.addListener(listener); - // } - - // Register a useradmin listener - listener = new MyUiUAListener(parent.getDisplay()); - userAdminWrapper.addListener(listener); - } - - private class MyUiUAListener extends UiUserAdminListener { - public MyUiUAListener(Display display) { - super(display); - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - if (userViewer != null && !userViewer.getTable().isDisposed()) - refresh(); - } - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private boolean showSystemRoles = false; - - private final String[] knownProps = { LdifName.uid.name(), - LdifName.cn.name(), LdifName.dn.name() }; - - public MyUserTableViewer(Composite parent, int style) { - super(parent, style); - } - - protected void populateStaticFilters(Composite staticFilterCmp) { - staticFilterCmp.setLayout(new GridLayout()); - final Button showSystemRoleBtn = new Button(staticFilterCmp, - SWT.CHECK); - showSystemRoleBtn.setText("Show system roles"); - showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -7033424592697691676L; - - @Override - public void widgetSelected(SelectionEvent e) { - showSystemRoles = showSystemRoleBtn.getSelection(); - refresh(); - } - - }); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - try { - StringBuilder builder = new StringBuilder(); - StringBuilder tmpBuilder = new StringBuilder(); - if (EclipseUiUtils.notEmpty(filter)) - for (String prop : knownProps) { - tmpBuilder.append("("); - tmpBuilder.append(prop); - tmpBuilder.append("=*"); - tmpBuilder.append(filter); - tmpBuilder.append("*)"); - } - if (tmpBuilder.length() > 1) { - builder.append("(&(").append(LdifName.objectClass.name()) - .append("=").append(LdifName.groupOfNames.name()) - .append(")"); - if (!showSystemRoles) - builder.append("(!(").append(LdifName.dn.name()) - .append("=*") - .append(AuthConstants.ROLES_BASEDN) - .append("))"); - builder.append("(|"); - builder.append(tmpBuilder.toString()); - builder.append("))"); - } else { - if (!showSystemRoles) - builder.append("(&(") - .append(LdifName.objectClass.name()) - .append("=") - .append(LdifName.groupOfNames.name()) - .append(")(!(").append(LdifName.dn.name()) - .append("=*") - .append(AuthConstants.ROLES_BASEDN) - .append(")))"); - else - builder.append("(").append(LdifName.objectClass.name()) - .append("=") - .append(LdifName.groupOfNames.name()) - .append(")"); - - } - roles = userAdminWrapper.getUserAdmin().getRoles( - builder.toString()); - } catch (InvalidSyntaxException e) { - throw new CmsException("Unable to get roles with filter: " - + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - if (!users.contains(role)) - users.add((User) role); - else - log.warn("Duplicated role: " + role); - - return users; - } - } - - public void refresh() { - groupTableViewerCmp.refresh(); - } - - // Override generic view methods - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @Override - public void setFocus() { - groupTableViewerCmp.setFocus(); - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserBatchUpdateWizard.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserBatchUpdateWizard.java deleted file mode 100644 index b532ddef5..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserBatchUpdateWizard.java +++ /dev/null @@ -1,578 +0,0 @@ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.transaction.SystemException; -import javax.transaction.UserTransaction; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.cms.auth.AuthConstants; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.providers.CommonNameLP; -import org.argeo.security.ui.admin.internal.providers.DomainNameLP; -import org.argeo.security.ui.admin.internal.providers.MailLP; -import org.argeo.security.ui.admin.internal.providers.UserNameLP; -import org.eclipse.jface.dialogs.IPageChangeProvider; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.wizard.IWizardContainer; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; - -/** Wizard to update users */ -public class UserBatchUpdateWizard extends Wizard { - - private final static Log log = LogFactory - .getLog(UserBatchUpdateWizard.class); - private UserAdminWrapper userAdminWrapper; - - // pages - private ChooseCommandWizardPage chooseCommandPage; - private ChooseUsersWizardPage userListPage; - private ValidateAndLaunchWizardPage validatePage; - - // Various implemented commands keys - private final static String CMD_UPDATE_PASSWORD = "resetPassword"; - private final static String CMD_GROUP_MEMBERSHIP = "groupMembership"; - - private final Map commands = new HashMap() { - private static final long serialVersionUID = 1L; - { - put("Reset password(s)", CMD_UPDATE_PASSWORD); - // TODO implement role / group management - // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP); - } - }; - - public UserBatchUpdateWizard(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } - - @Override - public void addPages() { - chooseCommandPage = new ChooseCommandWizardPage(); - addPage(chooseCommandPage); - userListPage = new ChooseUsersWizardPage(); - addPage(userListPage); - validatePage = new ValidateAndLaunchWizardPage(); - addPage(validatePage); - } - - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - UserTransaction ut = userAdminWrapper.getUserTransaction(); - try { - if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION - && !MessageDialog.openConfirm(getShell(), - "Existing Transaction", - "A user transaction is already existing, " - + "are you sure you want to proceed ?")) - return false; - } catch (SystemException e) { - throw new CmsException("Cannot get user transaction state " - + "before user batch update", e); - } - - // We cannot use jobs, user modifications are still meant to be done in - // the UIThread - // UpdateJob job = null; - // if (job != null) - // job.schedule(); - - if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) { - char[] newValue = chooseCommandPage.getPwdValue(); - if (newValue == null) - throw new CmsException( - "Password cannot be null or an empty string"); - ResetPassword job = new ResetPassword(userAdminWrapper, - userListPage.getSelectedUsers(), newValue); - job.doUpdate(); - } - return true; - } - - public boolean canFinish() { - if (this.getContainer().getCurrentPage() == validatePage) - return true; - return false; - } - - private class ResetPassword { - private char[] newPwd; - private UserAdminWrapper userAdminWrapper; - private List usersToUpdate; - - public ResetPassword(UserAdminWrapper userAdminWrapper, - List usersToUpdate, char[] newPwd) { - this.newPwd = newPwd; - this.usersToUpdate = usersToUpdate; - this.userAdminWrapper = userAdminWrapper; - } - - @SuppressWarnings("unchecked") - protected void doUpdate() { - userAdminWrapper.beginTransactionIfNeeded(); - try { - for (User user : usersToUpdate) { - // the char array is emptied after being used. - user.getCredentials().put(null, newPwd.clone()); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - } catch (Exception e) { - throw new CmsException("Cannot perform batch update on users", - e); - } finally { - UserTransaction ut = userAdminWrapper.getUserTransaction(); - try { - if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION) - ut.rollback(); - } catch (IllegalStateException | SecurityException - | SystemException e) { - log.error("Unable to rollback session in 'finally', " - + "the system might be in a dirty state"); - e.printStackTrace(); - } - } - } - } - - // @SuppressWarnings("unused") - // private class AddToGroup extends UpdateJob { - // private String groupID; - // private Session session; - // - // public AddToGroup(Session session, List nodesToUpdate, - // String groupID) { - // super(session, nodesToUpdate); - // this.session = session; - // this.groupID = groupID; - // } - // - // protected void doUpdate(Node node) { - // log.info("Add/Remove to group actions are not yet implemented"); - // // TODO implement this - // // try { - // // throw new CmsException("Not yet implemented"); - // // } catch (RepositoryException re) { - // // throw new CmsException( - // // "Unable to update boolean value for node " + node, re); - // // } - // } - // } - - // /** - // * Base privileged job that will be run asynchronously to perform the - // batch - // * update - // */ - // private abstract class UpdateJob extends PrivilegedJob { - // - // private final UserAdminWrapper userAdminWrapper; - // private final List usersToUpdate; - // - // protected abstract void doUpdate(User user); - // - // public UpdateJob(UserAdminWrapper userAdminWrapper, - // List usersToUpdate) { - // super("Perform update"); - // this.usersToUpdate = usersToUpdate; - // this.userAdminWrapper = userAdminWrapper; - // } - // - // @Override - // protected IStatus doRun(IProgressMonitor progressMonitor) { - // try { - // JcrMonitor monitor = new EclipseJcrMonitor(progressMonitor); - // int total = usersToUpdate.size(); - // monitor.beginTask("Performing change", total); - // userAdminWrapper.beginTransactionIfNeeded(); - // for (User user : usersToUpdate) { - // doUpdate(user); - // monitor.worked(1); - // } - // userAdminWrapper.getUserTransaction().commit(); - // } catch (Exception e) { - // throw new CmsException( - // "Cannot perform batch update on users", e); - // } finally { - // UserTransaction ut = userAdminWrapper.getUserTransaction(); - // try { - // if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION) - // ut.rollback(); - // } catch (IllegalStateException | SecurityException - // | SystemException e) { - // log.error("Unable to rollback session in 'finally', " - // + "the system might be in a dirty state"); - // e.printStackTrace(); - // } - // } - // return Status.OK_STATUS; - // } - // } - - // PAGES - /** Displays a combo box that enables user to choose which action to perform */ - private class ChooseCommandWizardPage extends WizardPage { - private static final long serialVersionUID = -8069434295293996633L; - private Combo chooseCommandCmb; - private Button trueChk; - private Text valueTxt; - private Text pwdTxt; - private Text pwd2Txt; - - public ChooseCommandWizardPage() { - super("Choose a command to run."); - setTitle("Choose a command to run."); - } - - @Override - public void createControl(Composite parent) { - GridLayout gl = new GridLayout(); - Composite container = new Composite(parent, SWT.NO_FOCUS); - container.setLayout(gl); - - chooseCommandCmb = new Combo(container, SWT.READ_ONLY); - chooseCommandCmb.setLayoutData(EclipseUiUtils.fillWidth()); - String[] values = commands.keySet().toArray(new String[0]); - chooseCommandCmb.setItems(values); - - final Composite bottomPart = new Composite(container, SWT.NO_FOCUS); - bottomPart.setLayoutData(EclipseUiUtils.fillAll()); - bottomPart.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - chooseCommandCmb.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 1L; - - @Override - public void widgetSelected(SelectionEvent e) { - if (getCommand().equals(CMD_UPDATE_PASSWORD)) - populatePasswordCmp(bottomPart); - else if (getCommand().equals(CMD_GROUP_MEMBERSHIP)) - populateGroupCmp(bottomPart); - else - populateBooleanFlagCmp(bottomPart); - checkPageComplete(); - bottomPart.layout(true, true); - } - }); - setControl(container); - } - - private void populateBooleanFlagCmp(Composite parent) { - EclipseUiUtils.clear(parent); - trueChk = new Button(parent, SWT.CHECK); - trueChk.setText("Do it. (It will to the contrary if unchecked)"); - trueChk.setSelection(true); - trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); - } - - private void populatePasswordCmp(Composite parent) { - EclipseUiUtils.clear(parent); - Composite body = new Composite(parent, SWT.NO_FOCUS); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = -1558726363536729634L; - - @Override - public void modifyText(ModifyEvent event) { - checkPageComplete(); - } - }; - - body.setLayout(new GridLayout(2, false)); - body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - pwdTxt = EclipseUiUtils.createGridLP(body, "New password", ml); - pwd2Txt = EclipseUiUtils.createGridLP(body, "Repeat password", ml); - } - - private void checkPageComplete() { - String errorMsg = null; - if (chooseCommandCmb.getSelectionIndex() < 0) - errorMsg = "Please select an action"; - else if (CMD_UPDATE_PASSWORD.equals(getCommand())) { - if (EclipseUiUtils.isEmpty(pwdTxt.getText()) - || pwdTxt.getText().length() < 4) - errorMsg = "Please enter a password that is at least 4 character long"; - else if (!pwdTxt.getText().equals(pwd2Txt.getText())) - errorMsg = "Passwords are different"; - } - if (EclipseUiUtils.notEmpty(errorMsg)) { - setMessage(errorMsg, WizardPage.ERROR); - setPageComplete(false); - } else { - setMessage("Page complete, you can proceed to user choice", - WizardPage.INFORMATION); - setPageComplete(true); - } - - getContainer().updateButtons(); - } - - private void populateGroupCmp(Composite parent) { - EclipseUiUtils.clear(parent); - trueChk = new Button(parent, SWT.CHECK); - trueChk.setText("Add to group. (It will remove user(s) from the " - + "corresponding group if unchecked)"); - trueChk.setSelection(true); - trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); - } - - protected String getCommand() { - return commands.get(chooseCommandCmb.getItem(chooseCommandCmb - .getSelectionIndex())); - } - - protected String getCommandLbl() { - return chooseCommandCmb.getItem(chooseCommandCmb - .getSelectionIndex()); - } - - @SuppressWarnings("unused") - protected boolean getBoleanValue() { - // FIXME this is not consistent and will lead to errors. - if (ArgeoNames.ARGEO_ENABLED.equals(getCommand())) - return trueChk.getSelection(); - else - return !trueChk.getSelection(); - } - - @SuppressWarnings("unused") - protected String getStringValue() { - String value = null; - if (valueTxt != null) { - value = valueTxt.getText(); - if ("".equals(value.trim())) - value = null; - } - return value; - } - - protected char[] getPwdValue() { - // We do not directly reset the password text fields: There is no - // need to over secure this process: setting a pwd to multi users - // at the same time is anyhow a bad practice and should be used only - // in test environment or for temporary access - if (pwdTxt == null || pwdTxt.isDisposed()) - return null; - else - return pwdTxt.getText().toCharArray(); - } - } - - /** - * Displays a list of users with a check box to be able to choose some of - * them - */ - private class ChooseUsersWizardPage extends WizardPage implements - IPageChangedListener { - private static final long serialVersionUID = 7651807402211214274L; - private ChooseUserTableViewer userTableCmp; - - public ChooseUsersWizardPage() { - super("Choose Users"); - setTitle("Select users who will be impacted"); - } - - @Override - public void createControl(Composite parent) { - Composite pageCmp = new Composite(parent, SWT.NONE); - pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - // Define the displayed columns - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), - "Common Name", 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", - 200)); - - // Only show technical DN to admin - if (UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN)) - columnDefs.add(new ColumnDefinition(new UserNameLP(), - "Distinguished Name", 300)); - - userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL); - userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); - userTableCmp.setColumnDefinitions(columnDefs); - userTableCmp.populate(true, true); - userTableCmp.refresh(); - - setControl(pageCmp); - - // Add listener to update message when shown - final IWizardContainer wContainer = this.getContainer(); - if (wContainer instanceof IPageChangeProvider) { - ((IPageChangeProvider) wContainer).addPageChangedListener(this); - } - - } - - @Override - public void pageChanged(PageChangedEvent event) { - if (event.getSelectedPage() == this) { - String msg = "Chosen batch action: " - + chooseCommandPage.getCommandLbl(); - ((WizardPage) event.getSelectedPage()).setMessage(msg); - } - } - - protected List getSelectedUsers() { - return userTableCmp.getSelectedUsers(); - } - - private class ChooseUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 5080437561015853124L; - private final String[] knownProps = { LdifName.uid.name(), - LdifName.dn.name(), LdifName.cn.name(), - LdifName.givenName.name(), LdifName.sn.name(), - LdifName.mail.name() }; - - public ChooseUserTableViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - - try { - StringBuilder builder = new StringBuilder(); - - StringBuilder tmpBuilder = new StringBuilder(); - if (EclipseUiUtils.notEmpty(filter)) - for (String prop : knownProps) { - tmpBuilder.append("("); - tmpBuilder.append(prop); - tmpBuilder.append("=*"); - tmpBuilder.append(filter); - tmpBuilder.append("*)"); - } - if (tmpBuilder.length() > 1) { - builder.append("(&(") - .append(LdifName.objectClass.name()) - .append("=") - .append(LdifName.inetOrgPerson.name()) - .append(")(|"); - builder.append(tmpBuilder.toString()); - builder.append("))"); - } else - builder.append("(").append(LdifName.objectClass.name()) - .append("=") - .append(LdifName.inetOrgPerson.name()) - .append(")"); - roles = userAdminWrapper.getUserAdmin().getRoles( - builder.toString()); - } catch (InvalidSyntaxException e) { - throw new CmsException("Unable to get roles with filter: " - + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - // Prevent current logged in user to perform batch on - // himself - if (!UserAdminUtils.isCurrentUser((User) role)) - users.add((User) role); - return users; - } - } - } - - /** Summary of input data before launching the process */ - private class ValidateAndLaunchWizardPage extends WizardPage implements - IPageChangedListener { - private static final long serialVersionUID = 7098918351451743853L; - private ChosenUsersTableViewer userTableCmp; - - public ValidateAndLaunchWizardPage() { - super("Validate and launch"); - setTitle("Validate and launch"); - } - - @Override - public void createControl(Composite parent) { - Composite pageCmp = new Composite(parent, SWT.NO_FOCUS); - pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), - "Common Name", 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", - 200)); - // Only show technical DN to admin - if (UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN)) - columnDefs.add(new ColumnDefinition(new UserNameLP(), - "Distinguished Name", 300)); - userTableCmp = new ChosenUsersTableViewer(pageCmp, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL); - userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); - userTableCmp.setColumnDefinitions(columnDefs); - userTableCmp.populate(false, false); - userTableCmp.refresh(); - setControl(pageCmp); - // Add listener to update message when shown - final IWizardContainer wContainer = this.getContainer(); - if (wContainer instanceof IPageChangeProvider) { - ((IPageChangeProvider) wContainer).addPageChangedListener(this); - } - } - - @Override - public void pageChanged(PageChangedEvent event) { - if (event.getSelectedPage() == this) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - Object[] values = ((ArrayList) userListPage.getSelectedUsers()) - .toArray(new Object[userListPage.getSelectedUsers() - .size()]); - userTableCmp.getTableViewer().setInput(values); - String msg = "Following batch action: [" - + chooseCommandPage.getCommandLbl() - + "] will be perfomed on the users listed below.\n"; - // + "Are you sure you want to proceed?"; - setMessage(msg); - } - } - - private class ChosenUsersTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 7814764735794270541L; - - public ChosenUsersTableViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - protected List listFilteredElements(String filter) { - return userListPage.getSelectedUsers(); - } - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java deleted file mode 100644 index f750e67bb..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.ArrayList; -import java.util.List; - -import org.argeo.cms.CmsException; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.security.ui.admin.internal.UiUserAdminListener; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.forms.AbstractFormPart; -import org.eclipse.ui.forms.editor.FormEditor; -import org.osgi.service.useradmin.Authorization; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Editor for a user, might be a user or a group. */ -public class UserEditor extends FormEditor { - private static final long serialVersionUID = 8357851520380820241L; - - public final static String USER_EDITOR_ID = SecurityUiPlugin.PLUGIN_ID - + ".userEditor"; - public final static String GROUP_EDITOR_ID = SecurityUiPlugin.PLUGIN_ID - + ".groupEditor"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - private UserAdmin userAdmin; - - // Context - private User user; - private String username; - - private NameChangeListener listener; - - public void init(IEditorSite site, IEditorInput input) - throws PartInitException { - super.init(site, input); - username = ((UserEditorInput) getEditorInput()).getUsername(); - user = (User) userAdmin.getRole(username); - - listener = new NameChangeListener(site.getShell().getDisplay(), user); - userAdminWrapper.addListener(listener); - updateEditorTitle(null); - } - - /** - * returns the list of all authorization for the given user or of the - * current displayed user if parameter is null - */ - protected List getFlatGroups(User aUser) { - Authorization currAuth; - if (aUser == null) - currAuth = userAdmin.getAuthorization(this.user); - else - currAuth = userAdmin.getAuthorization(aUser); - - String[] roles = currAuth.getRoles(); - - List groups = new ArrayList(); - for (String roleStr : roles) { - User currRole = (User) userAdmin.getRole(roleStr); - if (!groups.contains(currRole)) - groups.add(currRole); - } - return groups; - } - - /** Exposes the user (or group) that is displayed by the current editor */ - protected User getDisplayedUser() { - return user; - } - - void updateEditorTitle(String title) { - if (title == null) { - String commonName = UserAdminUtils.getProperty(user, - LdifName.cn.name()); - title = "".equals(commonName) ? user.getName() : commonName; - } - setPartName(title); - } - - protected void addPages() { - try { - if (user.getType() == Role.GROUP) - addPage(new GroupMainPage(this, userAdminWrapper)); - else - addPage(new UserMainPage(this, userAdminWrapper)); - } catch (Exception e) { - throw new CmsException("Cannot add pages", e); - } - } - - @Override - public void doSave(IProgressMonitor monitor) { - userAdminWrapper.beginTransactionIfNeeded(); - commitPages(true); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - firePropertyChange(PROP_DIRTY); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_REMOVED, user)); - } - - @Override - public void doSaveAs() { - } - - @Override - public boolean isSaveAsAllowed() { - return false; - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - // CONTROLERS FOR THIS EDITOR AND ITS PAGES - - private class NameChangeListener extends UiUserAdminListener { - - private final User user; - - public NameChangeListener(Display display, User user) { - super(display); - this.user = user; - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - Role changedRole = event.getRole(); - if (changedRole == null || changedRole.equals(user)) - updateEditorTitle(null); - } - } - - class MainInfoListener extends UiUserAdminListener { - private final AbstractFormPart part; - - public MainInfoListener(Display display, AbstractFormPart part) { - super(display); - this.part = part; - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - // Rollback - if (event.getRole() == null) - part.markStale(); - } - } - - class GroupChangeListener extends UiUserAdminListener { - private final AbstractFormPart part; - - public GroupChangeListener(Display display, AbstractFormPart part) { - super(display); - this.part = part; - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - // always mark as stale - part.markStale(); - } - } - - /** Registers a listener that will notify this part */ - class FormPartML implements ModifyListener { - private static final long serialVersionUID = 6299808129505381333L; - private AbstractFormPart formPart; - - public FormPartML(AbstractFormPart generalPart) { - this.formPart = generalPart; - } - - public void modifyText(ModifyEvent e) { - // Discard event when the control does not have the focus, typically - // to avoid all editors being marked as dirty during a Rollback - if (((Control) e.widget).isFocusControl()) - formPart.markDirty(); - } - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - this.userAdmin = userAdminWrapper.getUserAdmin(); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserEditorInput.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserEditorInput.java deleted file mode 100644 index fe129f815..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserEditorInput.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; - -/** - * Editor input for an user defined by unique name (usually a distinguished - * name). - */ -public class UserEditorInput implements IEditorInput { - private final String username; - - public UserEditorInput(String username) { - this.username = username; - } - - public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { - return null; - } - - public boolean exists() { - return username != null; - } - - public ImageDescriptor getImageDescriptor() { - return null; - } - - public String getName() { - return username != null ? username : ""; - } - - public IPersistableElement getPersistable() { - return null; - } - - public String getToolTipText() { - return username != null ? username : ""; - } - - public boolean equals(Object obj) { - if (!(obj instanceof UserEditorInput)) - return false; - if (((UserEditorInput) obj).getUsername() == null) - return false; - return ((UserEditorInput) obj).getUsername().equals(username); - } - - public String getUsername() { - return username; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java deleted file mode 100644 index df910ecea..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.argeo.cms.CmsException; -import org.argeo.cms.auth.AuthConstants; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.security.ui.admin.SecurityAdminImages; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.parts.UserEditor.GroupChangeListener; -import org.argeo.security.ui.admin.internal.parts.UserEditor.MainInfoListener; -import org.argeo.security.ui.admin.internal.providers.CommonNameLP; -import org.argeo.security.ui.admin.internal.providers.DomainNameLP; -import org.argeo.security.ui.admin.internal.providers.RoleIconLP; -import org.argeo.security.ui.admin.internal.providers.UserFilter; -import org.argeo.security.ui.admin.internal.providers.UserNameLP; -import org.argeo.security.ui.admin.internal.providers.UserTableDefaultDClickListener; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerDropAdapter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Cursor; -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.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.ui.forms.AbstractFormPart; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.SectionPart; -import org.eclipse.ui.forms.editor.FormEditor; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Display/edit the properties of a given user */ -public class UserMainPage extends FormPage implements ArgeoNames { - final static String ID = "UserEditor.mainPage"; - - private final UserEditor editor; - private UserAdminWrapper userAdminWrapper; - - // Local configuration - private final int PRE_TITLE_INDENT = 10; - - public UserMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) { - super(editor, ID, "Main"); - this.editor = (UserEditor) editor; - this.userAdminWrapper = userAdminWrapper; - } - - protected void createFormContent(final IManagedForm mf) { - ScrolledForm form = mf.getForm(); - Composite body = form.getBody(); - GridLayout mainLayout = new GridLayout(); - // mainLayout.marginRight = 10; - body.setLayout(mainLayout); - User user = editor.getDisplayedUser(); - appendOverviewPart(body, user); - // Remove to ability to force the password for his own user. The user - // must then use the change pwd feature - if (!UserAdminUtils.isCurrentUser(user)) - appendPasswordPart(body, user); - appendMemberOfPart(body, user); - } - - /** Creates the general section */ - private void appendOverviewPart(final Composite parent, final User user) { - FormToolkit tk = getManagedForm().getToolkit(); - - Section section = addSection(tk, parent, "Main information"); - Composite body = (Composite) section.getClient(); - body.setLayout(new GridLayout(2, false)); - - final Text distinguishedName = createLT(tk, body, "User Name", - UserAdminUtils.getProperty(user, LdifName.uid.name())); - distinguishedName.setEnabled(false); - - final Text commonName = createLT(tk, body, "Common Name", - UserAdminUtils.getProperty(user, LdifName.cn.name())); - commonName.setEnabled(false); - - final Text firstName = createLT(tk, body, "First name", - UserAdminUtils.getProperty(user, LdifName.givenName.name())); - - final Text lastName = createLT(tk, body, "Last name", - UserAdminUtils.getProperty(user, LdifName.sn.name())); - - final Text email = createLT(tk, body, "Email", - UserAdminUtils.getProperty(user, LdifName.mail.name())); - - // create form part (controller) - AbstractFormPart part = new SectionPart((Section) body.getParent()) { - private MainInfoListener listener; - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = editor.new MainInfoListener(parent.getDisplay(), - this); - userAdminWrapper.addListener(listener); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @SuppressWarnings("unchecked") - public void commit(boolean onSave) { - // TODO Sanity checks (mail validity...) - user.getProperties().put(LdifName.givenName.name(), - firstName.getText()); - user.getProperties() - .put(LdifName.sn.name(), lastName.getText()); - user.getProperties().put(LdifName.cn.name(), - commonName.getText()); - user.getProperties().put(LdifName.mail.name(), email.getText()); - super.commit(onSave); - } - - @Override - public void refresh() { - distinguishedName.setText(UserAdminUtils.getProperty(user, - LdifName.uid.name())); - commonName.setText(UserAdminUtils.getProperty(user, - LdifName.cn.name())); - firstName.setText(UserAdminUtils.getProperty(user, - LdifName.givenName.name())); - lastName.setText(UserAdminUtils.getProperty(user, - LdifName.sn.name())); - email.setText(UserAdminUtils.getProperty(user, - LdifName.mail.name())); - refreshFormTitle(user); - super.refresh(); - } - }; - - // Improve this: automatically generate CN when first or last name - // changes - ModifyListener cnML = new ModifyListener() { - private static final long serialVersionUID = 4298649222869835486L; - - @Override - public void modifyText(ModifyEvent event) { - String first = firstName.getText(); - String last = lastName.getText(); - String cn = first.trim() + " " + last.trim() + " "; - cn = cn.trim(); - commonName.setText(cn); - getManagedForm().getForm().setText(cn); - editor.updateEditorTitle(cn); - } - }; - firstName.addModifyListener(cnML); - lastName.addModifyListener(cnML); - - ModifyListener defaultListener = editor.new FormPartML(part); - firstName.addModifyListener(defaultListener); - lastName.addModifyListener(defaultListener); - email.addModifyListener(defaultListener); - getManagedForm().addPart(part); - } - - /** Creates the password section */ - private void appendPasswordPart(Composite parent, final User user) { - FormToolkit tk = getManagedForm().getToolkit(); - Section section = addSection(tk, parent, "Password"); - Composite body = (Composite) section.getClient(); - body.setLayout(new GridLayout(2, false)); - - // add widgets (view) - final Text password1 = createLP(tk, body, "New password", ""); - final Text password2 = createLP(tk, body, "Repeat password", ""); - - // create form part (controller) - AbstractFormPart part = new SectionPart((Section) body.getParent()) { - @SuppressWarnings("unchecked") - public void commit(boolean onSave) { - if (!password1.getText().equals("") - || !password2.getText().equals("")) { - if (password1.getText().equals(password2.getText())) { - char[] newPassword = password1.getText().toCharArray(); - // userAdminWrapper.beginTransactionIfNeeded(); - user.getCredentials().put(null, newPassword); - password1.setText(""); - password2.setText(""); - super.commit(onSave); - } else { - password1.setText(""); - password2.setText(""); - throw new CmsException("Passwords are not equals"); - } - } - } - }; - ModifyListener defaultListener = editor.new FormPartML(part); - password1.addModifyListener(defaultListener); - password2.addModifyListener(defaultListener); - getManagedForm().addPart(part); - } - - private LdifUsersTable appendMemberOfPart(final Composite parent, User user) { - FormToolkit tk = getManagedForm().getToolkit(); - Section section = addSection(tk, parent, "Roles"); - Composite body = (Composite) section.getClient(); - body.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - boolean isAdmin = UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN); - - // Displayed columns - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", - 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain Name", - 200)); - // Only show technical DN to administrators - if (isAdmin) - columnDefs.add(new ColumnDefinition(new UserNameLP(), - "Distinguished Name", 120)); - - // Create and configure the table - final LdifUsersTable userViewerCmp = new MyUserTableViewer(body, - SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, user); - - userViewerCmp.setColumnDefinitions(columnDefs); - if (isAdmin) - userViewerCmp.populateWithStaticFilters(false, false); - else - userViewerCmp.populate(true, false); - GridData gd = EclipseUiUtils.fillAll(); - gd.heightHint = 300; - userViewerCmp.setLayoutData(gd); - - // Controllers - TableViewer userViewer = userViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - GroupDropListener dropL = new GroupDropListener(userAdminWrapper, - userViewer, user); - userViewer.addDropSupport(operations, tt, dropL); - - SectionPart part = new SectionPart((Section) body.getParent()) { - - private GroupChangeListener listener; - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = editor.new GroupChangeListener(parent.getDisplay(), - this); - userAdminWrapper.addListener(listener); - } - - public void commit(boolean onSave) { - super.commit(onSave); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @Override - public void refresh() { - userViewerCmp.refresh(); - super.refresh(); - } - }; - getManagedForm().addPart(part); - addRemoveAbitily(part, userViewer, user); - return userViewerCmp; - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 2653790051461237329L; - - private Button showSystemRoleBtn; - - private final User user; - private final UserFilter userFilter; - - public MyUserTableViewer(Composite parent, int style, User user) { - super(parent, style, true); - this.user = user; - userFilter = new UserFilter(); - userFilter.setShowSystemRole(false); - } - - protected void populateStaticFilters(Composite staticFilterCmp) { - staticFilterCmp.setLayout(new GridLayout()); - showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); - showSystemRoleBtn.setText("Show system roles"); - showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -7033424592697691676L; - - @Override - public void widgetSelected(SelectionEvent e) { - userFilter.setShowSystemRole(showSystemRoleBtn - .getSelection()); - refresh(); - } - }); - } - - @Override - protected List listFilteredElements(String filter) { - List users = (List) editor.getFlatGroups(null); - List filteredUsers = new ArrayList(); - if (users.contains(user)) - users.remove(user); - userFilter.setSearchText(filter); - for (User user : users) - if (userFilter.select(null, null, user)) - filteredUsers.add(user); - return filteredUsers; - } - } - - private void addRemoveAbitily(SectionPart sectionPart, - TableViewer userViewer, User user) { - Section section = sectionPart.getSection(); - ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - ToolBar toolbar = toolBarManager.createControl(section); - final Cursor handCursor = new Cursor(section.getDisplay(), - SWT.CURSOR_HAND); - toolbar.setCursor(handCursor); - toolbar.addDisposeListener(new DisposeListener() { - private static final long serialVersionUID = 3882131405820522925L; - - public void widgetDisposed(DisposeEvent e) { - if ((handCursor != null) && (handCursor.isDisposed() == false)) { - handCursor.dispose(); - } - } - }); - - String tooltip = "Remove " + UserAdminUtils.getUsername(user) - + " from the below selected groups"; - Action action = new RemoveMembershipAction(userViewer, user, tooltip, - SecurityAdminImages.ICON_REMOVE_DESC); - toolBarManager.add(action); - toolBarManager.update(true); - section.setTextClient(toolbar); - } - - private class RemoveMembershipAction extends Action { - private static final long serialVersionUID = -1337713097184522588L; - - private final TableViewer userViewer; - private final User user; - - RemoveMembershipAction(TableViewer userViewer, User user, String name, - ImageDescriptor img) { - super(name, img); - this.userViewer = userViewer; - this.user = user; - } - - @Override - public void run() { - ISelection selection = userViewer.getSelection(); - if (selection.isEmpty()) - return; - - @SuppressWarnings("unchecked") - Iterator it = ((IStructuredSelection) selection).iterator(); - List groups = new ArrayList(); - while (it.hasNext()) { - Group currGroup = it.next(); - groups.add(currGroup); - } - - userAdminWrapper.beginTransactionIfNeeded(); - for (Group group : groups) { - group.removeMember(user); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - for (Group group : groups) { - userAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CHANGED, group)); - } - } - } - - /** - * Defines the table as being a potential target to add group memberships - * (roles) to this user - */ - private class GroupDropListener extends ViewerDropAdapter { - private static final long serialVersionUID = 2893468717831451621L; - - private final UserAdminWrapper myUserAdminWrapper; - private final User myUser; - - public GroupDropListener(UserAdminWrapper userAdminWrapper, - Viewer userViewer, User user) { - super(userViewer); - this.myUserAdminWrapper = userAdminWrapper; - this.myUser = user; - } - - @Override - public boolean validateDrop(Object target, int operation, - TransferData transferType) { - // Target is always OK in a list only view - // TODO check if not a string - boolean validDrop = true; - return validDrop; - } - - @Override - public void drop(DropTargetEvent event) { - String name = (String) event.data; - UserAdmin myUserAdmin = myUserAdminWrapper.getUserAdmin(); - Role role = myUserAdmin.getRole(name); - // TODO this check should be done before. - if (role.getType() == Role.GROUP) { - // TODO check if the user is already member of this group - - myUserAdminWrapper.beginTransactionIfNeeded(); - Group group = (Group) role; - group.addMember(myUser); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - myUserAdminWrapper.notifyListeners(new UserAdminEvent(null, - UserAdminEvent.ROLE_CHANGED, group)); - } - super.drop(event); - } - - @Override - public boolean performDrop(Object data) { - // userTableViewerCmp.refresh(); - return true; - } - } - - // LOCAL HELPERS - private void refreshFormTitle(User group) { - getManagedForm().getForm().setText( - UserAdminUtils.getProperty(group, LdifName.cn.name())); - } - - /** Appends a section with a title */ - private Section addSection(FormToolkit tk, Composite parent, String title) { - Section section = tk.createSection(parent, Section.TITLE_BAR); - GridData gd = EclipseUiUtils.fillWidth(); - gd.verticalAlignment = PRE_TITLE_INDENT; - section.setLayoutData(gd); - section.setText(title); - // section.getMenu().setVisible(true); - - Composite body = tk.createComposite(section, SWT.WRAP); - body.setLayoutData(EclipseUiUtils.fillAll()); - section.setClient(body); - - return section; - } - - /** Creates label and multiline text. */ - Text createLMT(FormToolkit toolkit, Composite body, String label, - String value) { - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - return text; - } - - /** Creates label and password. */ - Text createLP(FormToolkit toolkit, Composite body, String label, - String value) { - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return text; - } - - /** Creates label and text. */ - Text createLT(FormToolkit toolkit, Composite body, String label, - String value) { - Label lbl = toolkit.createLabel(body, label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Text text = toolkit.createText(body, value, SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return text; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UsersView.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UsersView.java deleted file mode 100644 index a811cd5a5..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/parts/UsersView.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.admin.internal.parts; - -import java.util.ArrayList; -import java.util.List; - -import org.argeo.cms.CmsException; -import org.argeo.cms.auth.AuthConstants; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.node.ArgeoNames; -import org.argeo.osgi.useradmin.LdifName; -import org.argeo.security.ui.admin.internal.UiUserAdminListener; -import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.providers.CommonNameLP; -import org.argeo.security.ui.admin.internal.providers.DomainNameLP; -import org.argeo.security.ui.admin.internal.providers.MailLP; -import org.argeo.security.ui.admin.internal.providers.UserDragListener; -import org.argeo.security.ui.admin.internal.providers.UserNameLP; -import org.argeo.security.ui.admin.internal.providers.UserTableDefaultDClickListener; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.part.ViewPart; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** List all users with filter - based on Ldif userAdmin */ -public class UsersView extends ViewPart implements ArgeoNames { - // private final static Log log = LogFactory.getLog(UsersView.class); - - public final static String ID = SecurityUiPlugin.PLUGIN_ID + ".usersView"; - - /* DEPENDENCY INJECTION */ - private UserAdminWrapper userAdminWrapper; - - // UI Objects - private LdifUsersTable userTableViewerCmp; - private TableViewer userViewer; - private List columnDefs = new ArrayList(); - - private UserAdminListener listener; - - @Override - public void createPartControl(Composite parent) { - - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - // Define the displayed columns - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", - 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); - // Only show technical DN to admin - if (UserAdminUtils.isUserInRole(AuthConstants.ROLE_ADMIN)) - columnDefs.add(new ColumnDefinition(new UserNameLP(), - "Distinguished Name", 300)); - - // Create and configure the table - userTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL); - userTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); - userTableViewerCmp.setColumnDefinitions(columnDefs); - userTableViewerCmp.populate(true, false); - - // Links - userViewer = userTableViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener()); - getViewSite().setSelectionProvider(userViewer); - - // Really? - userTableViewerCmp.refresh(); - - // Drag and drop - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - userViewer.addDragSupport(operations, tt, new UserDragListener( - userViewer)); - - // Register a useradmin listener - listener = new MyUiUAListener(parent.getDisplay()); - userAdminWrapper.addListener(listener); - } - - private class MyUiUAListener extends UiUserAdminListener { - public MyUiUAListener(Display display) { - super(display); - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - if (userViewer != null && !userViewer.getTable().isDisposed()) - refresh(); - } - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private final String[] knownProps = { LdifName.uid.name(), - LdifName.dn.name(), LdifName.cn.name(), - LdifName.givenName.name(), LdifName.sn.name(), - LdifName.mail.name() }; - - public MyUserTableViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - - try { - StringBuilder builder = new StringBuilder(); - - StringBuilder tmpBuilder = new StringBuilder(); - if (EclipseUiUtils.notEmpty(filter)) - for (String prop : knownProps) { - tmpBuilder.append("("); - tmpBuilder.append(prop); - tmpBuilder.append("=*"); - tmpBuilder.append(filter); - tmpBuilder.append("*)"); - } - if (tmpBuilder.length() > 1) { - builder.append("(&(").append(LdifName.objectClass.name()) - .append("=").append(LdifName.inetOrgPerson.name()) - .append(")(|"); - builder.append(tmpBuilder.toString()); - builder.append("))"); - } else - builder.append("(").append(LdifName.objectClass.name()) - .append("=").append(LdifName.inetOrgPerson.name()) - .append(")"); - roles = userAdminWrapper.getUserAdmin().getRoles( - builder.toString()); - } catch (InvalidSyntaxException e) { - throw new CmsException("Unable to get roles with filter: " - + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - // if (role.getType() == Role.USER && role.getType() != - // Role.GROUP) - users.add((User) role); - return users; - } - } - - public void refresh() { - userTableViewerCmp.refresh(); - } - - // Override generic view methods - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @Override - public void setFocus() { - userTableViewerCmp.setFocus(); - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java deleted file mode 100644 index d45c0b603..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.osgi.useradmin.LdifName; -import org.osgi.service.useradmin.User; - -/** Simply declare a label provider that returns the common name of a user */ -public class CommonNameLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 5256703081044911941L; - - @Override - public String getText(User user) { - return UserAdminUtils.getProperty(user, LdifName.cn.name()); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java deleted file mode 100644 index 795fd0af3..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.osgi.service.useradmin.User; - -/** The human friendly domain name for the corresponding user. */ -public class DomainNameLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 5256703081044911941L; - - @Override - public String getText(User user) { - return UserAdminUtils.getDomainName(user); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/MailLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/MailLP.java deleted file mode 100644 index 0a6dcb604..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/MailLP.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.osgi.useradmin.LdifName; -import org.osgi.service.useradmin.User; - -/** Simply declare a label provider that returns the Primary Mail of a user */ -public class MailLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 8329764452141982707L; - - @Override - public String getText(User user) { - return UserAdminUtils.getProperty(user, LdifName.mail.name()); - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java deleted file mode 100644 index bb19220a9..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.argeo.cms.auth.AuthConstants; -import org.argeo.security.ui.admin.SecurityAdminImages; -import org.eclipse.swt.graphics.Image; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; - -/** Provide a bundle specific image depending on the current user type */ -public class RoleIconLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 6550449442061090388L; - - @Override - public String getText(User user) { - return ""; - } - - @Override - public Image getImage(Object element) { - User user = (User) element; - String dn = user.getName(); - if (dn.endsWith(AuthConstants.ROLES_BASEDN)) - return SecurityAdminImages.ICON_ROLE; - else if (user.getType() == Role.GROUP) - return SecurityAdminImages.ICON_GROUP; - else - return SecurityAdminImages.ICON_USER; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java deleted file mode 100644 index 2b0a13db7..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -import org.argeo.cms.CmsException; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.widgets.Display; -import org.osgi.service.useradmin.User; - -/** - * Utility class that add font modifications to a column label provider - * depending on the given user properties - */ -public abstract class UserAdminAbstractLP extends ColumnLabelProvider { - private static final long serialVersionUID = 137336765024922368L; - - // private Font italic; - private Font bold; - - @Override - public Font getFont(Object element) { - // Self as bold - try { - LdapName selfUserName = UserAdminUtils.getCurrentUserLdapName(); - String userName = ((User) element).getName(); - LdapName userLdapName = new LdapName(userName); - if (userLdapName.equals(selfUserName)) { - if (bold == null) - bold = JFaceResources.getFontRegistry() - .defaultFontDescriptor().setStyle(SWT.BOLD) - .createFont(Display.getCurrent()); - return bold; - } - } catch (InvalidNameException e) { - throw new CmsException("cannot parse dn for " + element, e); - } - - // Disabled as Italic - // Node userProfile = (Node) elem; - // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) - // return italic; - - return null; - // return super.getFont(element); - } - - @Override - public String getText(Object element) { - User user = (User) element; - return getText(user); - } - - public void setDisplay(Display display) { - // italic = JFaceResources.getFontRegistry().defaultFontDescriptor() - // .setStyle(SWT.ITALIC).createFont(display); - bold = JFaceResources.getFontRegistry().defaultFontDescriptor() - .setStyle(SWT.BOLD).createFont(Display.getCurrent()); - } - - public abstract String getText(User user); -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java deleted file mode 100644 index f60b64c65..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.dnd.DragSourceEvent; -import org.eclipse.swt.dnd.DragSourceListener; -import org.osgi.service.useradmin.User; - -/** Default drag listener to modify group and users via the UI */ -public class UserDragListener implements DragSourceListener { - private static final long serialVersionUID = -2074337775033781454L; - private final Viewer viewer; - - public UserDragListener(Viewer viewer) { - this.viewer = viewer; - } - - public void dragStart(DragSourceEvent event) { - // TODO implement finer checks - IStructuredSelection selection = (IStructuredSelection) viewer - .getSelection(); - if (selection.isEmpty() || selection.size() > 1) - event.doit = false; - else - event.doit = true; - } - - public void dragSetData(DragSourceEvent event) { - // TODO Support multiple selection - Object obj = ((IStructuredSelection) viewer.getSelection()) - .getFirstElement(); - if (obj != null) { - User user = (User) obj; - event.data = user.getName(); - } - } - - public void dragFinished(DragSourceEvent event) { - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserFilter.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserFilter.java deleted file mode 100644 index 5f753d1c3..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserFilter.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; - -import org.argeo.cms.auth.AuthConstants; -import org.argeo.cms.util.useradmin.UserAdminUtils; -import org.argeo.osgi.useradmin.LdifName; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.osgi.service.useradmin.User; - -public class UserFilter extends ViewerFilter { - private static final long serialVersionUID = 5082509381672880568L; - - private String searchString; - private boolean showSystemRole = true; - - private final String[] knownProps = { LdifName.dn.name(), - LdifName.cn.name(), LdifName.givenName.name(), LdifName.sn.name(), - LdifName.uid.name(), LdifName.description.name(), - LdifName.mail.name() }; - - public void setSearchText(String s) { - // ensure that the value can be used for matching - if (notEmpty(s)) - searchString = ".*" + s.toLowerCase() + ".*"; - else - searchString = ".*"; - } - - public void setShowSystemRole(boolean showSystemRole) { - this.showSystemRole = showSystemRole; - } - - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - User user = (User) element; - if (!showSystemRole - && user.getName().matches( - ".*(" + AuthConstants.ROLES_BASEDN + ")")) - // UserAdminUtils.getProperty(user, LdifName.dn.name()) - // .toLowerCase().endsWith(AuthConstants.ROLES_BASEDN)) - return false; - - if (searchString == null || searchString.length() == 0) - return true; - - if (user.getName().matches(searchString)) - return true; - - for (String key : knownProps) { - String currVal = UserAdminUtils.getProperty(user, key); - if (notEmpty(currVal) - && currVal.toLowerCase().matches(searchString)) - return true; - } - return false; - } - -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserNameLP.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserNameLP.java deleted file mode 100644 index a2a15c112..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserNameLP.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.osgi.service.useradmin.User; - -/** Simply declare a label provider that returns the username of a user */ -public class UserNameLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 6550449442061090388L; - - @Override - public String getText(User user) { - return user.getName(); - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java deleted file mode 100644 index 10337bebd..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import org.argeo.cms.CmsException; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.security.ui.admin.internal.parts.UserEditor; -import org.argeo.security.ui.admin.internal.parts.UserEditorInput; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.User; - -/** - * Default double click listener for the various user tables, will open the - * clicked item in the editor - */ -public class UserTableDefaultDClickListener implements IDoubleClickListener { - public void doubleClick(DoubleClickEvent evt) { - if (evt.getSelection().isEmpty()) - return; - Object obj = ((IStructuredSelection) evt.getSelection()) - .getFirstElement(); - User user = (User) obj; - IWorkbenchWindow iww = SecurityUiPlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow(); - IWorkbenchPage iwp = iww.getActivePage(); - UserEditorInput uei = new UserEditorInput(user.getName()); - - try { - // Works around the fact that dynamic setting of the editor icon - // causes NPE after a login/logout on RAP - if (user instanceof Group) - iwp.openEditor(uei, UserEditor.GROUP_EDITOR_ID); - else - iwp.openEditor(uei, UserEditor.USER_EDITOR_ID); - } catch (PartInitException pie) { - throw new CmsException("Unable to open UserEditor for " + user, pie); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java deleted file mode 100644 index 33b3cb7c8..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.argeo.security.ui.admin.internal.providers; - -import java.util.HashMap; -import java.util.Map; - -import javax.transaction.Status; -import javax.transaction.UserTransaction; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.eclipse.ui.AbstractSourceProvider; -import org.eclipse.ui.ISources; - -/** Observe and notify UI on UserTransaction state changes */ -public class UserTransactionProvider extends AbstractSourceProvider { - private final static Log log = LogFactory - .getLog(UserTransactionProvider.class); - - public final static String TRANSACTION_STATE = SecurityUiPlugin.PLUGIN_ID - + ".userTransactionState"; - public final static String STATUS_ACTIVE = "status.active"; - public final static String STATUS_NO_TRANSACTION = "status.noTransaction"; - - /* DEPENDENCY INJECTION */ - private UserTransaction userTransaction; - - @Override - public String[] getProvidedSourceNames() { - return new String[] { TRANSACTION_STATE }; - } - - @Override - public Map getCurrentState() { - Map currentState = new HashMap(1); - currentState.put(TRANSACTION_STATE, getInternalCurrentState()); - return currentState; - } - - @Override - public void dispose() { - } - - private String getInternalCurrentState() { - try { - String transactionState; - if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) - transactionState = STATUS_NO_TRANSACTION; - else - // if (userTransaction.getStatus() == Status.STATUS_ACTIVE) - transactionState = STATUS_ACTIVE; - return transactionState; - } catch (Exception e) { - throw new CmsException("Unable to begin transaction", e); - } - } - - /** Publishes the ability to notify a state change */ - public void fireTransactionStateChange() { - try { - fireSourceChanged(ISources.WORKBENCH, TRANSACTION_STATE, - getInternalCurrentState()); - } catch (Exception e) { - log.warn("Cannot fire transaction state change event. Caught exception: " - + e.getClass().getCanonicalName() + " - " + e.getMessage()); - } - } - - /* DEPENDENCY INJECTION */ - public void setUserTransaction(UserTransaction userTransaction) { - this.userTransaction = userTransaction; - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java deleted file mode 100644 index 817354f70..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.commands; - -import static org.argeo.cms.CmsMsg.changePassword; -import static org.argeo.cms.CmsMsg.currentPassword; -import static org.argeo.cms.CmsMsg.newPassword; -import static org.argeo.cms.CmsMsg.passwordChanged; -import static org.argeo.cms.CmsMsg.repeatNewPassword; -import static org.eclipse.jface.dialogs.IMessageProvider.INFORMATION; - -import java.security.AccessController; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.security.auth.Subject; -import javax.security.auth.x500.X500Principal; -import javax.transaction.UserTransaction; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.handlers.HandlerUtil; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; - -/** Opens the change password dialog. */ -public class OpenChangePasswordDialog extends AbstractHandler { - private final static Log log = LogFactory - .getLog(OpenChangePasswordDialog.class); - private UserAdmin userAdmin; - private UserTransaction userTransaction; - - public Object execute(ExecutionEvent event) throws ExecutionException { - ChangePasswordDialog dialog = new ChangePasswordDialog( - HandlerUtil.getActiveShell(event), userAdmin); - if (dialog.open() == Dialog.OK) { - MessageDialog.openInformation(HandlerUtil.getActiveShell(event), - passwordChanged.lead(), passwordChanged.lead()); - } - return null; - } - - @SuppressWarnings("unchecked") - protected void changePassword(char[] oldPassword, char[] newPassword) { - Subject subject = Subject.getSubject(AccessController.getContext()); - String name = subject.getPrincipals(X500Principal.class).iterator() - .next().toString(); - LdapName dn; - try { - dn = new LdapName(name); - } catch (InvalidNameException e) { - throw new CmsException("Invalid user dn " + name, e); - } - User user = (User) userAdmin.getRole(dn.toString()); - if (!user.hasCredential(null, oldPassword)) - throw new CmsException("Invalid password"); - if (newPassword.equals("")) - throw new CmsException("New password empty"); - try { - userTransaction.begin(); - user.getCredentials().put(null, newPassword); - userTransaction.commit(); - } catch (Exception e) { - try { - userTransaction.rollback(); - } catch (Exception e1) { - log.error("Could not roll back", e1); - } - if (e instanceof RuntimeException) - throw (RuntimeException) e; - else - throw new CmsException("Cannot change password", e); - } - } - - public void setUserAdmin(UserAdmin userDetailsManager) { - this.userAdmin = userDetailsManager; - } - - public void setUserTransaction(UserTransaction userTransaction) { - this.userTransaction = userTransaction; - } - - class ChangePasswordDialog extends TitleAreaDialog { - private static final long serialVersionUID = -6963970583882720962L; - private Text oldPassword, newPassword1, newPassword2; - - public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) { - super(parentShell); - } - - protected Point getInitialSize() { - return new Point(400, 450); - } - - protected Control createDialogArea(Composite parent) { - Composite dialogarea = (Composite) super.createDialogArea(parent); - dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - true)); - Composite composite = new Composite(dialogarea, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); - oldPassword = createLP(composite, currentPassword.lead()); - newPassword1 = createLP(composite, newPassword.lead()); - newPassword2 = createLP(composite, repeatNewPassword.lead()); - - setMessage(changePassword.lead(), INFORMATION); - parent.pack(); - return composite; - } - - @Override - protected void okPressed() { - try { - if (!newPassword1.getText().equals(newPassword2.getText())) - throw new CmsException("New passwords are different"); - changePassword(oldPassword.getTextChars(), - newPassword1.getTextChars()); - close(); - } catch (Exception e) { - ErrorFeedback.show("Cannot change password", e); - } - } - - /** Creates label and password. */ - protected Text createLP(Composite parent, String label) { - new Label(parent, SWT.NONE).setText(label); - Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD - | SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - return text; - } - - protected void configureShell(Shell shell) { - super.configureShell(shell); - shell.setText(changePassword.lead()); - } - - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/commands/OpenHomePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/commands/OpenHomePerspective.java deleted file mode 100644 index f6aa0d19e..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/commands/OpenHomePerspective.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.commands; - -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.security.ui.UserHomePerspective; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.ui.WorkbenchException; -import org.eclipse.ui.handlers.HandlerUtil; - -/** Default action of the user menu */ -public class OpenHomePerspective extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - try { - HandlerUtil.getActiveSite(event).getWorkbenchWindow() - .openPage(UserHomePerspective.ID, null); - } catch (WorkbenchException e) { - ErrorFeedback.show("Cannot open home perspective", e); - } - return null; - } -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/AdminLogView.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/AdminLogView.java deleted file mode 100644 index cb3b02f41..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/AdminLogView.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.views; - -import java.util.ArrayList; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.node.ArgeoLogger; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.ui.part.ViewPart; - -/** - * Display log lines for all users with a virtual table. - */ -public class AdminLogView extends ViewPart { - public static String ID = SecurityUiPlugin.PLUGIN_ID + ".adminLogView"; - - private TableViewer viewer; - - private LogContentProvider logContentProvider; - private ArgeoLogger argeoLogger; - - @Override - public void createPartControl(Composite parent) { - // FIXME doesn't return a monospace font in RAP - Font font = JFaceResources.getTextFont(); - Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL - | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); - table.setFont(font); - - viewer = new TableViewer(table); - viewer.setLabelProvider(new LabelProvider()); - logContentProvider = new LogContentProvider(viewer) { - private static final long serialVersionUID = -3401776448301180724L; - - @Override - protected StringBuffer prefix(String username, Long timestamp, - String level, String category, String thread) { - return super - .prefix(username, timestamp, level, category, thread) - .append(norm(level, 5)) - .append(' ') - .append(norm(username != null ? username - : "", 16)).append(' '); - } - }; - viewer.setContentProvider(logContentProvider); - // viewer.setUseHashlookup(true); - viewer.setInput(new ArrayList()); - - if (argeoLogger != null) - argeoLogger.registerForAll(logContentProvider, 1000, true); - } - - @Override - public void setFocus() { - viewer.getTable().setFocus(); - } - - @Override - public void dispose() { - if (argeoLogger != null) - argeoLogger.unregisterForAll(logContentProvider); - } - - public void setArgeoLogger(ArgeoLogger argeoLogger) { - this.argeoLogger = argeoLogger; - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/LogContentProvider.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/LogContentProvider.java deleted file mode 100644 index 5b12f439a..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/LogContentProvider.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.views; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -import org.argeo.node.ArgeoLogListener; -import org.eclipse.jface.viewers.ILazyContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; - -/** A content provider maintaining an array of lines */ -class LogContentProvider implements ILazyContentProvider, ArgeoLogListener { - private static final long serialVersionUID = -2084872367738339721L; - - private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); - - private final Long start; - /** current - start = line number. first line is number '1' */ - private Long current; - - // TODO make it configurable - private final Integer maxLineBufferSize = 10 * 1000; - - private final TableViewer viewer; - private LinkedList lines; - - public LogContentProvider(TableViewer viewer) { - this.viewer = viewer; - start = System.currentTimeMillis(); - lines = new LinkedList(); - current = start; - } - - public synchronized void dispose() { - lines.clear(); - lines = null; - } - - @SuppressWarnings("unchecked") - public synchronized void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - List lin = (List) newInput; - if (lin == null) - return; - for (String line : lin) { - addLine(line); - } - this.viewer.setItemCount(lines.size()); - } - - public void updateElement(int index) { - viewer.replace(lines.get(index), index); - } - - public synchronized void appendLog(String username, Long timestamp, - String level, String category, String thread, Object msg, - String[] exception) { - // check if valid - if (lines == null) - return; - - String message = msg.toString(); - int count = 0; - String prefix = prefix(username, timestamp, level, category, thread) - .toString(); - // String suffix = suffix(username, timestamp, level, category, thread); - for (String line : message.split("\n")) { - addLine(count == 0 ? prefix + line : line); - count++; - } - - if (exception != null) { - for (String ste : exception) { - addLine(ste); - } - } - - viewer.getTable().getDisplay().asyncExec(new Runnable() { - public void run() { - if (lines == null) - return; - viewer.setItemCount(lines.size()); - // doesn't work with syncExec - scrollToLastLine(); - } - }); - } - - protected StringBuffer prefix(String username, Long timestamp, - String level, String category, String thread) { - StringBuffer buf = new StringBuffer(""); - buf.append(dateFormat.format(new Date(timestamp))).append(" "); - // buf.append(level).append(" "); - return buf; - } - - /** Normalize string to the given size */ - protected String norm(String str, Integer size) { - int length = str.length(); - if (length == size) - return str; - else if (length > size) - return str.substring(0, size); - else { - char[] arr = new char[size - length]; - Arrays.fill(arr, ' '); - return str + new String(arr); - } - } - - // protected String suffix(String username, Long timestamp, String level, - // String category, String thread) { - // return ""; - // } - - /** Scroll to the last line */ - protected synchronized void scrollToLastLine() { - // we try to show last line with two methods - // viewer.reveal(lines.peekLast()); - - Table table = viewer.getTable(); - TableItem ti = table.getItem(table.getItemCount() - 1); - table.showItem(ti); - } - - protected synchronized LogLine addLine(String line) { - // check for maximal size and purge if necessary - while (lines.size() >= maxLineBufferSize) { - for (int i = 0; i < maxLineBufferSize / 10; i++) { - lines.poll(); - } - } - - current++; - LogLine logLine = new LogLine(current, line); - lines.add(logLine); - return logLine; - } - - private class LogLine { - private Long linenumber; - private String message; - - public LogLine(Long linenumber, String message) { - this.linenumber = linenumber; - this.message = message; - } - - @Override - public int hashCode() { - return linenumber.intValue(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof LogLine) - return ((LogLine) obj).linenumber.equals(linenumber); - else - return false; - } - - @Override - public String toString() { - return message; - } - - } -} \ No newline at end of file diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/LogView.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/LogView.java deleted file mode 100644 index 50d44416b..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/LogView.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.views; - -import java.util.ArrayList; - -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.node.ArgeoLogListener; -import org.argeo.node.ArgeoLogger; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.ui.part.ViewPart; - -/** - * Display log lines with a virtual table. Register and unregisters a - * {@link ArgeoLogListener} via OSGi services. - */ -public class LogView extends ViewPart { - public static String ID = SecurityUiPlugin.PLUGIN_ID + ".logView"; - - private TableViewer viewer; - - private LogContentProvider logContentProvider; - private ArgeoLogger argeoLogger; - - @Override - public void createPartControl(Composite parent) { - Font font = JFaceResources.getTextFont(); - Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL - | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); - table.setFont(font); - - viewer = new TableViewer(table); - viewer.setLabelProvider(new LabelProvider()); - logContentProvider = new LogContentProvider(viewer); - viewer.setContentProvider(logContentProvider); - // viewer.setUseHashlookup(true); - viewer.setInput(new ArrayList()); - - if (argeoLogger != null) - argeoLogger.register(logContentProvider, 1000); - } - - @Override - public void setFocus() { - viewer.getTable().setFocus(); - } - - @Override - public void dispose() { - if (argeoLogger != null) - argeoLogger.unregister(logContentProvider); - } - - public void setArgeoLogger(ArgeoLogger argeoLogger) { - this.argeoLogger = argeoLogger; - } - -} diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/UserProfile.java b/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/UserProfile.java deleted file mode 100644 index b7b929b88..000000000 --- a/org.argeo.cms.ui.workbench/src/org/argeo/security/ui/views/UserProfile.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.argeo.security.ui.views; - -import java.util.TreeSet; - -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.ui.workbench.SecurityUiPlugin; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.ui.part.ViewPart; - -/** Information about the currently logged in user */ -public class UserProfile extends ViewPart { - public static String ID = SecurityUiPlugin.PLUGIN_ID + ".userProfile"; - - private TableViewer viewer; - - @Override - public void createPartControl(Composite parent) { - parent.setLayout(new GridLayout(2, false)); - - // Authentication authentication = CurrentUser.getAuthentication(); - // EclipseUiUtils.createGridLL(parent, "Name", authentication - // .getPrincipal().toString()); - EclipseUiUtils.createGridLL(parent, "User ID", - CurrentUser.getUsername()); - - // roles table - Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER); - table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - table.setLinesVisible(false); - table.setHeaderVisible(false); - viewer = new TableViewer(table); - viewer.setContentProvider(new RolesContentProvider()); - viewer.setLabelProvider(new LabelProvider()); - getViewSite().setSelectionProvider(viewer); - viewer.setInput(getViewSite()); - } - - @Override - public void setFocus() { - viewer.getTable(); - } - - private class RolesContentProvider implements IStructuredContentProvider { - private static final long serialVersionUID = -4576917440167866233L; - - public Object[] getElements(Object inputElement) { - return new TreeSet(CurrentUser.roles()).toArray(); - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - } - -}