From afd41f657b0eecb1e9a1db85af8bff0cc7bc4804 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Mon, 3 Oct 2011 14:29:48 +0000 Subject: [PATCH] Working JCR based preferences git-svn-id: https://svn.argeo.org/commons/trunk@4787 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../org.argeo.demo.i18n/META-INF/MANIFEST.MF | 5 +- .../META-INF/spring/editors.xml | 10 ++ .../META-INF/spring/jcr.xml | 24 +++++ .../META-INF/spring/osgi.xml | 3 + demo/plugins/org.argeo.demo.i18n/plugin.xml | 2 +- .../i18n/preferences/LocaleSettingsPage.java | 4 +- .../eclipse/ui/jcr/JcrPreferenceStore.java | 78 +++++++++++--- .../jackrabbit/ArgeoSecurityManager.java | 63 ++++++----- .../META-INF/MANIFEST.MF | 1 + .../editors/NodeRightsManagementPage.java | 101 ++++++++++++++++-- .../jackrabbit/JackrabbitAuthorizations.java | 47 ++++---- .../main/java/org/argeo/jcr/ArgeoTypes.java | 1 + .../src/main/java/org/argeo/jcr/JcrUtils.java | 20 ++++ .../main/resources/org/argeo/jcr/argeo.cnd | 6 +- 14 files changed, 289 insertions(+), 76 deletions(-) create mode 100644 demo/plugins/org.argeo.demo.i18n/META-INF/spring/jcr.xml diff --git a/demo/plugins/org.argeo.demo.i18n/META-INF/MANIFEST.MF b/demo/plugins/org.argeo.demo.i18n/META-INF/MANIFEST.MF index 6ba788ac8..68d10e5b0 100644 --- a/demo/plugins/org.argeo.demo.i18n/META-INF/MANIFEST.MF +++ b/demo/plugins/org.argeo.demo.i18n/META-INF/MANIFEST.MF @@ -13,12 +13,15 @@ Require-Bundle: org.eclipse.ui;resolution:=optional, org.eclipse.core.runtime;resolution:=optional, org.eclipse.rap.ui;resolution:=optional, org.eclipse.rap.ui.workbench;resolution:=optional -Import-Package: org.apache.commons.io, +Import-Package: javax.jcr;version="2.0.0", + org.apache.commons.io, org.apache.commons.logging, org.argeo, org.argeo.eclipse.spring, org.argeo.eclipse.ui, + org.argeo.eclipse.ui.jcr, org.argeo.eclipse.ui.utils, + org.argeo.jcr.spring, org.eclipse.ui.forms, org.eclipse.ui.forms.editor, org.eclipse.ui.forms.widgets diff --git a/demo/plugins/org.argeo.demo.i18n/META-INF/spring/editors.xml b/demo/plugins/org.argeo.demo.i18n/META-INF/spring/editors.xml index 6d0951720..12c9c3b99 100644 --- a/demo/plugins/org.argeo.demo.i18n/META-INF/spring/editors.xml +++ b/demo/plugins/org.argeo.demo.i18n/META-INF/spring/editors.xml @@ -8,4 +8,14 @@ + + + + + + + + diff --git a/demo/plugins/org.argeo.demo.i18n/META-INF/spring/jcr.xml b/demo/plugins/org.argeo.demo.i18n/META-INF/spring/jcr.xml new file mode 100644 index 000000000..11986aa3d --- /dev/null +++ b/demo/plugins/org.argeo.demo.i18n/META-INF/spring/jcr.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/demo/plugins/org.argeo.demo.i18n/META-INF/spring/osgi.xml b/demo/plugins/org.argeo.demo.i18n/META-INF/spring/osgi.xml index 83ab12d74..14ce7af5e 100644 --- a/demo/plugins/org.argeo.demo.i18n/META-INF/spring/osgi.xml +++ b/demo/plugins/org.argeo.demo.i18n/META-INF/spring/osgi.xml @@ -8,4 +8,7 @@ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" osgi:default-timeout="30000"> + + \ No newline at end of file diff --git a/demo/plugins/org.argeo.demo.i18n/plugin.xml b/demo/plugins/org.argeo.demo.i18n/plugin.xml index b7a16db60..0b7bd0997 100644 --- a/demo/plugins/org.argeo.demo.i18n/plugin.xml +++ b/demo/plugins/org.argeo.demo.i18n/plugin.xml @@ -70,7 +70,7 @@ diff --git a/demo/plugins/org.argeo.demo.i18n/src/main/java/org/argeo/demo/i18n/preferences/LocaleSettingsPage.java b/demo/plugins/org.argeo.demo.i18n/src/main/java/org/argeo/demo/i18n/preferences/LocaleSettingsPage.java index 50df00f5a..fa6e34dcc 100644 --- a/demo/plugins/org.argeo.demo.i18n/src/main/java/org/argeo/demo/i18n/preferences/LocaleSettingsPage.java +++ b/demo/plugins/org.argeo.demo.i18n/src/main/java/org/argeo/demo/i18n/preferences/LocaleSettingsPage.java @@ -1,6 +1,5 @@ package org.argeo.demo.i18n.preferences; -import org.argeo.demo.i18n.I18nDemoPlugin; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.RadioGroupFieldEditor; @@ -31,7 +30,6 @@ public class LocaleSettingsPage extends FieldEditorPreferencePage implements @Override public void init(IWorkbench workbench) { - setPreferenceStore(I18nDemoPlugin.getDefault().getPreferenceStore()); - setDescription("A demonstration of a preference page implementation"); } + } diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrPreferenceStore.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrPreferenceStore.java index f8dc23f47..1018ddd29 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrPreferenceStore.java +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrPreferenceStore.java @@ -10,30 +10,60 @@ 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.ArgeoException; import org.argeo.jcr.ArgeoNames; +import org.argeo.jcr.ArgeoTypes; import org.argeo.jcr.JcrUtils; import org.eclipse.jface.preference.PreferenceStore; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.framework.BundleContext; -/** Persist preferences as key/value pairs under ~/argeo:preferences */ -public class JcrPreferenceStore extends PreferenceStore { +/** + * Persist preferences as key/value pairs under ~/argeo:preferences.
+ * TODO: better integrate JCR and Eclipse:
+ * - typing
+ * - use eclipse preferences
+ * - better integrate with {@link ScopedPreferenceStore} provided by RAP + */ +public class JcrPreferenceStore extends PreferenceStore implements ArgeoNames { private Session session; + private BundleContext bundleContext; /** Retrieves the preference node */ protected Node getPreferenceNode() { try { + if (session.hasPendingChanges()) + session.save(); Node userHome = JcrUtils.getUserHome(session); + if (userHome == null) + throw new ArgeoException("No user home for " + + session.getUserID()); Node preferences; - if (!userHome.hasNode(ArgeoNames.ARGEO_PREFERENCES)) { - preferences = userHome.addNode(ArgeoNames.ARGEO_PREFERENCES); + if (!userHome.hasNode(ARGEO_PREFERENCES)) { + preferences = userHome.addNode(ARGEO_PREFERENCES); + preferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE); session.save(); - } else { - preferences = userHome.getNode(ArgeoNames.ARGEO_PREFERENCES); - } - return preferences; + } 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 ArgeoException("Cannot retrieve preferences", e); } @@ -49,7 +79,7 @@ public class JcrPreferenceStore extends PreferenceStore { PropertyIterator it = getPreferenceNode().getProperties(); while (it.hasNext()) { Property p = it.nextProperty(); - if (!p.isMultiple()) { + if (!p.isMultiple() && !p.getDefinition().isProtected()) { props.setProperty(p.getName(), p.getValue().getString()); } } @@ -58,6 +88,7 @@ public class JcrPreferenceStore extends PreferenceStore { in = new ByteArrayInputStream(out.toByteArray()); load(in); } catch (Exception e) { + e.printStackTrace(); throw new ArgeoException("Cannot load preferences", e); } finally { IOUtils.closeQuietly(in); @@ -69,31 +100,48 @@ public class JcrPreferenceStore extends PreferenceStore { public void save() throws IOException { ByteArrayOutputStream out = null; ByteArrayInputStream in = null; - Node preferences = null; + Node pluginPreferences = null; try { out = new ByteArrayOutputStream(); save(out, ""); in = new ByteArrayInputStream(out.toByteArray()); Properties props = new Properties(); props.load(in); - preferences = getPreferenceNode(); + 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); - preferences.setProperty(name, value); + pluginPreferences.setProperty(name, value); } - preferences.getSession().save(); + JcrUtils.updateLastModified(pluginPreferences); + pluginPreferences.getSession().save(); + vm.checkin(pluginPreferences.getPath()); } catch (Exception e) { - JcrUtils.discardUnderlyingSessionQuietly(preferences); - throw new ArgeoException("Cannot load preferences", e); + JcrUtils.discardUnderlyingSessionQuietly(pluginPreferences); + throw new ArgeoException("Cannot save preferences", e); } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(out); } } + public void init() { + try { + load(); + } catch (IOException e) { + throw new ArgeoException("Cannot initialize preference store", e); + } + } + public void setSession(Session session) { this.session = session; } + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + } diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java index bf33b8a28..c68a0c978 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java @@ -2,15 +2,18 @@ package org.argeo.security.jackrabbit; import java.security.Principal; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import javax.jcr.Node; +import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.security.AccessControlList; -import javax.jcr.security.AccessControlManager; +import javax.jcr.Value; +import javax.jcr.ValueFactory; import javax.jcr.security.AccessControlPolicy; import javax.jcr.security.AccessControlPolicyIterator; import javax.jcr.security.Privilege; @@ -18,6 +21,9 @@ import javax.security.auth.Subject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; @@ -100,35 +106,44 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { String userId = ""; try { userId = user.getID(); - Node userHome = JcrUtils.getUserHome(getSystemSession(), userId); - // autocreate home node? -// if (userHome == null) -// userHome = JcrUtils.createUserHome(getSystemSession(), -// HOME_BASE_PATH, userId); + Node userHome = null; + try { + userHome = JcrUtils.getUserHome(getSystemSession(), userId); + if (userHome == null) + userHome = JcrUtils.createUserHome(getSystemSession(), + HOME_BASE_PATH, userId); + } catch (Exception e) { + // silent + } if (userHome != null) { String path = userHome.getPath(); - AccessControlPolicy policy = null; - AccessControlManager acm = getSystemSession() + Principal principal = user.getPrincipal(); + + JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) getSystemSession() .getAccessControlManager(); - AccessControlPolicyIterator policyIterator = acm - .getApplicablePolicies(path); - if (policyIterator.hasNext()) { - policy = policyIterator.nextAccessControlPolicy(); - } else { - AccessControlPolicy[] existingPolicies = acm - .getPolicies(path); - policy = existingPolicies[0]; - } - if (policy instanceof AccessControlList) { - Privilege[] privileges = { acm - .privilegeFromName(Privilege.JCR_ALL) }; - ((AccessControlList) policy).addAccessControlEntry( - user.getPrincipal(), privileges); - acm.setPolicy(path, policy); + JackrabbitAccessControlPolicy[] ps = acm + .getApplicablePolicies(principal); + if (ps.length == 0) { + log.warn("No ACL found for " + user); + return; } + + JackrabbitAccessControlList list = (JackrabbitAccessControlList) ps[0]; + + // add entry + Privilege[] privileges = new Privilege[] { acm + .privilegeFromName(Privilege.JCR_ALL) }; + Map restrictions = new HashMap(); + ValueFactory vf = getSystemSession().getValueFactory(); + restrictions.put("rep:nodePath", + vf.createValue(path, PropertyType.PATH)); + restrictions.put("rep:glob", vf.createValue("*")); + list.addEntry(principal, privileges, true /* allow or deny */, + restrictions); } } catch (Exception e) { + e.printStackTrace(); log.warn("Cannot set authorization on user node for " + userId + ": " + e.getMessage()); } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/MANIFEST.MF b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/MANIFEST.MF index 4572f0a44..49269f09f 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/MANIFEST.MF +++ b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Bundle-ActivationPolicy: lazy Import-Package: javax.jcr, javax.jcr.nodetype, javax.jcr.observation, + javax.jcr.security;version="2.0.0", javax.jcr.version, org.apache.commons.io, org.apache.commons.logging, diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/NodeRightsManagementPage.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/NodeRightsManagementPage.java index e5c1752bb..d941cff19 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/NodeRightsManagementPage.java +++ b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/NodeRightsManagementPage.java @@ -1,10 +1,21 @@ package org.argeo.jcr.ui.explorer.editors; import javax.jcr.Node; +import javax.jcr.security.AccessControlManager; +import javax.jcr.security.Privilege; +import org.argeo.ArgeoException; +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.layout.GridLayout; -import org.eclipse.swt.widgets.Label; +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; @@ -19,6 +30,8 @@ public class NodeRightsManagementPage extends FormPage { private Node currentNode; + private TableViewer viewer; + public NodeRightsManagementPage(FormEditor editor, String title, Node currentNode) { super(editor, "NodeRightsManagementPage", title); @@ -26,15 +39,81 @@ public class NodeRightsManagementPage extends FormPage { } 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("Implement this for node " + currentNode.getPath()); - } catch (Exception e) { - e.printStackTrace(); + ScrolledForm form = managedForm.getForm(); + form.setText("Rights"); + FillLayout mainLayout = new FillLayout(); + form.getBody().setLayout(mainLayout); + createRightsPart(form.getBody()); + } + + /** Creates the rights section */ + 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); + + // check column + TableViewerColumn column = createTableViewerColumn(viewer, "checked", + 20); + column.setLabelProvider(new ColumnLabelProvider() { + public String getText(Object element) { + return null; + } + + public Image getImage(Object element) { + return null; + } + }); + // column.setEditingSupport(new RoleEditingSupport(rolesViewer, part)); + + // role column + column = createTableViewerColumn(viewer, "Role", 200); + column.setLabelProvider(new ColumnLabelProvider() { + public String getText(Object element) { + Privilege p = (Privilege) element; + return p.getName(); + } + + 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 { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getElements(Object inputElement) { + try { + AccessControlManager accessControlManager = currentNode + .getSession().getAccessControlManager(); + Privilege[] privileges = accessControlManager + .getPrivileges(currentNode.getPath()); + return privileges; + } catch (Exception e) { + throw new ArgeoException("Cannot retrieve rights", e); + } } + } } diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java index 8c1204c0e..3a731df58 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java @@ -17,6 +17,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; +import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.UserManager; import org.argeo.ArgeoException; @@ -87,31 +88,37 @@ public class JackrabbitAuthorizations { Group group = (Group) um.getAuthorizable(groupName); if (group == null) group = um.createGroup(groupName); - - AccessControlPolicy policy = null; - AccessControlPolicyIterator policyIterator = acm - .getApplicablePolicies(path); - if (policyIterator.hasNext()) { - policy = policyIterator.nextAccessControlPolicy(); - } else { - AccessControlPolicy[] existingPolicies = acm - .getPolicies(path); - policy = existingPolicies[0]; - } - if (policy instanceof AccessControlList) { - ((AccessControlList) policy).addAccessControlEntry( - group.getPrincipal(), - privs.toArray(new Privilege[privs.size()])); - acm.setPolicy(path, policy); - } - if (log.isDebugEnabled()) - log.debug("Added privileges " + privileges + " to " - + groupName + " on " + path); + addPrivileges(session, group, path, privs); } } session.save(); } + public static void addPrivileges(JackrabbitSession session, + Authorizable authorizable, String path, List privs) + throws RepositoryException { + JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session + .getAccessControlManager(); + AccessControlPolicy policy = null; + AccessControlPolicyIterator policyIterator = acm + .getApplicablePolicies(path); + if (policyIterator.hasNext()) { + policy = policyIterator.nextAccessControlPolicy(); + } else { + AccessControlPolicy[] existingPolicies = acm.getPolicies(path); + policy = existingPolicies[0]; + } + if (policy instanceof AccessControlList) { + ((AccessControlList) policy).addAccessControlEntry( + authorizable.getPrincipal(), + privs.toArray(new Privilege[privs.size()])); + acm.setPolicy(path, policy); + } + if (log.isDebugEnabled()) + log.debug("Added privileges " + privs + " to " + authorizable + + " on " + path); + } + public void setGroupPrivileges(Map groupPrivileges) { this.groupPrivileges = groupPrivileges; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java index 7416759b8..f59c97749 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java @@ -6,6 +6,7 @@ public interface ArgeoTypes { public final static String ARGEO_USER_HOME = "argeo:userHome"; public final static String ARGEO_USER_PROFILE = "argeo:userProfile"; public final static String ARGEO_REMOTE_REPOSITORY = "argeo:remoteRepository"; + public final static String ARGEO_PREFERENCE_NODE = "argeo:preferenceNode"; // tabular public final static String ARGEO_TABLE = "argeo:table"; diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java index 760e66009..d9da84ab3 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java @@ -223,6 +223,26 @@ public class JcrUtils implements ArgeoJcrConstants { return path.substring(index + 1); } + /** + * Routine that get the child with this name, adding id it does not already + * exist + */ + public static Node getOrAdd(Node parent, String childName, + String childPrimaryNodeType) throws RepositoryException { + return parent.hasNode(childName) ? parent.getNode(childName) : parent + .addNode(childName, childPrimaryNodeType); + } + + /** + * Routine that get the child with this name, adding id it does not already + * exist + */ + public static Node getOrAdd(Node parent, String childName) + throws RepositoryException { + return parent.hasNode(childName) ? parent.getNode(childName) : parent + .addNode(childName); + } + /** Creates the nodes making path, if they don't exist. */ public static Node mkdirs(Session session, String path) { return mkdirs(session, path, null, null, false); diff --git a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd index 315e2c244..48bb997c6 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd +++ b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd @@ -13,12 +13,16 @@ mixin - argeo:userID (STRING) m + argeo:profile (argeo:userProfile) + argeo:keyring (argeo:pbeSpec) -+ argeo:preferences (nt:unstructured) ++ argeo:preferences (argeo:preferenceNode) [argeo:userProfile] > mix:created, mix:lastModified, mix:title, mix:versionable mixin - argeo:userID (STRING) m +[argeo:preferenceNode] > mix:lastModified, mix:versionable +mixin ++ * (argeo:preferenceNode) * version + [argeo:remoteRepository] > nt:unstructured - argeo:uri (STRING) - argeo:userID (STRING) -- 2.30.2