From: Mathieu Baudier Date: Mon, 20 Jun 2022 10:42:19 +0000 (+0200) Subject: Improve ACR viewer. X-Git-Tag: v2.3.10~180 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=5c9bae758b5bb13ff3b046ad680886ae540865e8;p=lgpl%2Fargeo-commons.git Improve ACR viewer. --- diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/AcrContentTreeView.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/AcrContentTreeView.java deleted file mode 100644 index 98fabf060..000000000 --- a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/AcrContentTreeView.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.argeo.cms.swt.acr; - -import javax.xml.namespace.QName; - -import org.argeo.api.acr.Content; -import org.argeo.cms.swt.CmsSwtUtils; -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.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; - -public class AcrContentTreeView extends Composite { - private static final long serialVersionUID = -3707881216246077323L; - private SwtContentHierarchicalPart hPart; -// private Tree tree; - private Table table; - private Content rootContent; - - private Content selected; - - public AcrContentTreeView(Composite parent, int style, Content content) { - super(parent, style); - this.rootContent = content; - this.selected = rootContent; - setLayout(new GridLayout(2, false)); - initTree(); - GridData treeGd = CmsSwtUtils.fillHeight(); - treeGd.widthHint = 300; - hPart.getArea().setLayoutData(treeGd); - initTable(); - - table.setLayoutData(CmsSwtUtils.fillAll()); - } - - protected void initTree() { - hPart = new SwtContentHierarchicalPart(this, getStyle()); - hPart.setInput(rootContent); - hPart.onSelected((o) -> { - Content content = (Content) o; - selected = content; - refreshTable(); - - }); -// tree = new Tree(this, 0); -// for (Content c : rootContent) { -// TreeItem root = new TreeItem(tree, 0); -// root.setText(c.getName().toString()); -// root.setData(c); -// new TreeItem(root, 0); -// } -// tree.addListener(SWT.Expand, event -> { -// final TreeItem root = (TreeItem) event.item; -// TreeItem[] items = root.getItems(); -// for (TreeItem item : items) { -// if (item.getData() != null) -// return; -// item.dispose(); -// } -// Content content = (Content) root.getData(); -// for (Content c : content) { -// TreeItem item = new TreeItem(root, 0); -// item.setText(c.getName().toString()); -// item.setData(c); -// boolean hasChildren = true; -// if (hasChildren) { -// new TreeItem(item, 0); -// } -// } -// }); -// tree.addListener(SWT.Selection, event -> { -// TreeItem item = (TreeItem) event.item; -// selected = (Content) item.getData(); -// refreshTable(); -// }); - } - - protected void initTable() { - table = new Table(this, 0); - table.setLinesVisible(true); - table.setHeaderVisible(true); - TableColumn keyCol = new TableColumn(table, SWT.NONE); - keyCol.setText("Attribute"); - keyCol.setWidth(200); - TableColumn valueCol = new TableColumn(table, SWT.NONE); - valueCol.setText("Value"); - keyCol.setWidth(300); - refreshTable(); - } - - protected void refreshTable() { - for (TableItem item : table.getItems()) { - item.dispose(); - } - for (QName key : selected.keySet()) { - TableItem item = new TableItem(table, 0); - item.setText(0, key.toString()); - Object value = selected.get(key); - item.setText(1, value.toString()); - } - table.getColumn(0).pack(); - table.getColumn(1).pack(); - } - -// public static void main(String[] args) { -// Path basePath; -// if (args.length > 0) { -// basePath = Paths.get(args[0]); -// } else { -// basePath = Paths.get(System.getProperty("user.home")); -// } -// -// final Display display = new Display(); -// final Shell shell = new Shell(display); -// shell.setText(basePath.toString()); -// shell.setLayout(new FillLayout()); -// -// FsContentProvider contentSession = new FsContentProvider("/", basePath); -//// GcrContentTreeView treeView = new GcrContentTreeView(shell, 0, contentSession.get("/")); -// -// shell.setSize(shell.computeSize(800, 600)); -// shell.open(); -// while (!shell.isDisposed()) { -// if (!display.readAndDispatch()) -// display.sleep(); -// } -// display.dispose(); -// } -} diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/AcrContentTreeView.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/AcrContentTreeView.java new file mode 100644 index 000000000..cfae59b49 --- /dev/null +++ b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/AcrContentTreeView.java @@ -0,0 +1,152 @@ +package org.argeo.cms.swt.app; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.argeo.api.acr.Content; +import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.acr.SwtContentHierarchicalPart; +import org.argeo.cms.swt.widgets.SwtTabularPart; +import org.argeo.cms.ux.widgets.Column; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +public class AcrContentTreeView extends Composite { + private static final long serialVersionUID = -3707881216246077323L; + + private Content rootContent; + + private Content selected; + + public AcrContentTreeView(Composite parent, int style, Content content) { + super(parent, style); + this.rootContent = content; + this.selected = rootContent; + setLayout(CmsSwtUtils.noSpaceGridLayout()); + + SashForm split = new SashForm(this, SWT.HORIZONTAL); + split.setLayoutData(CmsSwtUtils.fillAll()); + + SwtContentHierarchicalPart hPart = new SwtContentHierarchicalPart(split, getStyle()); + Composite area = new Composite(split, SWT.NONE); + area.setLayout(CmsSwtUtils.noSpaceGridLayout(2)); + split.setWeights(new int[] { 30, 70 }); + + // attributes + SwtTabularPart attributesPart = new SwtTabularPart(area, SWT.NONE) { + List data; + + @Override + protected Object getData(int row) { + return data.get(row); + } + + @Override + protected int getItemCount() { + data = new ArrayList<>(selected.keySet()); + return data.size(); + } + }; + attributesPart.getArea().setLayoutData(CmsSwtUtils.fillHeight()); + + attributesPart.addColumn(new Column() { + + @Override + public String getText(QName model) { + return model.toString(); + } + }); + attributesPart.addColumn(new Column() { + + @Override + public String getText(QName model) { + return selected.get(model).toString(); + } + + @Override + public int getWidth() { + return 400; + } + + }); + + // types + SwtTabularPart typesPart = new SwtTabularPart(area, SWT.NONE) { + List data; + + @Override + protected Object getData(int row) { + return data.get(row); + } + + @Override + protected int getItemCount() { + data = new ArrayList<>(selected.getTypes()); + return data.size(); + } + }; + typesPart.addColumn(new Column() { + + @Override + public String getText(QName model) { + return model.toString(); + } + }); + typesPart.getArea().setLayoutData(CmsSwtUtils.fillHeight()); + + // controller + hPart.setInput(rootContent); + hPart.onSelected((o) -> { + Content c = (Content) o; + selected = c; + attributesPart.refresh(); + typesPart.refresh(); + }); + + attributesPart.refresh(); + typesPart.refresh(); + } + +// protected void refreshTable() { +// for (TableItem item : table.getItems()) { +// item.dispose(); +// } +// for (QName key : selected.keySet()) { +// TableItem item = new TableItem(table, 0); +// item.setText(0, key.toString()); +// Object value = selected.get(key); +// item.setText(1, value.toString()); +// } +// table.getColumn(0).pack(); +// table.getColumn(1).pack(); +// } + +// public static void main(String[] args) { +// Path basePath; +// if (args.length > 0) { +// basePath = Paths.get(args[0]); +// } else { +// basePath = Paths.get(System.getProperty("user.home")); +// } +// +// final Display display = new Display(); +// final Shell shell = new Shell(display); +// shell.setText(basePath.toString()); +// shell.setLayout(new FillLayout()); +// +// FsContentProvider contentSession = new FsContentProvider("/", basePath); +//// GcrContentTreeView treeView = new GcrContentTreeView(shell, 0, contentSession.get("/")); +// +// shell.setSize(shell.computeSize(800, 600)); +// shell.open(); +// while (!shell.isDisposed()) { +// if (!display.readAndDispatch()) +// display.sleep(); +// } +// display.dispose(); +// } +} diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java index 064c7e686..2eb2ce5dd 100644 --- a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java +++ b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java @@ -11,7 +11,6 @@ import org.argeo.api.cms.CmsView; import org.argeo.cms.AbstractCmsApp; import org.argeo.cms.swt.CmsSwtUi; import org.argeo.cms.swt.CmsSwtUtils; -import org.argeo.cms.swt.acr.AcrContentTreeView; import org.argeo.cms.swt.auth.CmsLogin; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabularPart.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabularPart.java index 02f2f8153..9872551be 100644 --- a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabularPart.java +++ b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabularPart.java @@ -3,12 +3,14 @@ package org.argeo.cms.swt.widgets; import java.util.function.Consumer; import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.ux.widgets.Column; import org.argeo.cms.ux.widgets.TabularPart; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; /** {@link TabularPart} implementation based on a {@link Table}. */ @@ -24,6 +26,7 @@ public class SwtTabularPart implements TabularPart { area = new Composite(parent, style); area.setLayout(CmsSwtUtils.noSpaceGridLayout()); table = new Table(area, SWT.VIRTUAL | SWT.BORDER); + table.setLinesVisible(true); } @Override @@ -67,13 +70,23 @@ public class SwtTabularPart implements TabularPart { } protected void refreshItem(TableItem item) { - + int row = getTable().indexOf(item); + for (int i = 0; i < item.getParent().getColumnCount(); i++) { + Column column = (Column) item.getParent().getColumn(i).getData(); + Object data = getData(row); + String text = data != null ? column.getText(data) : ""; + item.setText(i, text); + } } protected int getItemCount() { return 0; } + protected Object getData(int row) { + return null; + } + protected Table getTable() { return table; } @@ -86,4 +99,16 @@ public class SwtTabularPart implements TabularPart { this.onAction = onAction; } + @Override + public void addColumn(Column column) { + TableColumn swtColumn = new TableColumn(table, SWT.NONE); + swtColumn.setWidth(column.getWidth()); + swtColumn.setData(column); + + } + + public Composite getArea() { + return area; + } + } diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java index a7a9ecce0..41672a0e9 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java @@ -307,7 +307,7 @@ public class JcrContent extends AbstractContent { NodeType primaryType = context.getPrimaryNodeType(); res.add(nodeTypeToQName(primaryType)); - Set secondaryTypes = new TreeSet<>(); + Set secondaryTypes = new TreeSet<>(NamespaceUtils.QNAME_COMPARATOR); for (NodeType mixinType : context.getMixinNodeTypes()) { secondaryTypes.add(nodeTypeToQName(mixinType)); } diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/Column.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/Column.java new file mode 100644 index 000000000..5890fc4f8 --- /dev/null +++ b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/Column.java @@ -0,0 +1,9 @@ +package org.argeo.cms.ux.widgets; + +public interface Column { + String getText(T model); + + default int getWidth() { + return 200; + } +} diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TabularPart.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TabularPart.java index 40a56eb52..4c9320268 100644 --- a/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TabularPart.java +++ b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TabularPart.java @@ -1,5 +1,5 @@ package org.argeo.cms.ux.widgets; public interface TabularPart extends ColumnsPart { - + void addColumn(Column column); } diff --git a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java index 18c6724ac..c8ba7311d 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java @@ -16,6 +16,7 @@ import org.argeo.api.acr.Content; import org.argeo.api.acr.CrName; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.util.LangUtils; /** Partial reference implementation of a {@link ProvidedContent}. */ public abstract class AbstractContent extends AbstractMap implements ProvidedContent { @@ -152,9 +153,9 @@ public abstract class AbstractContent extends AbstractMap impleme /* * DEFAULTS */ - // - no children - // - no attributes - // - cannot be modified + // - no children + // - no attributes + // - cannot be modified @Override public Iterator iterator() { return Collections.emptyIterator(); @@ -226,12 +227,7 @@ public abstract class AbstractContent extends AbstractMap impleme @Override public int size() { - - int count = 0; - for (Iterator it = keys().iterator(); it.hasNext();) { - count++; - } - return count; + return LangUtils.size(keys()); } } diff --git a/org.argeo.cms/src/org/argeo/cms/acr/directory/RoleContent.java b/org.argeo.cms/src/org/argeo/cms/acr/directory/RoleContent.java index 344dede76..bf3b319f4 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/directory/RoleContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/directory/RoleContent.java @@ -79,17 +79,16 @@ class RoleContent extends AbstractContent { @Override public List getTypes() { List contentClasses = new ArrayList<>(); - keys: for (Enumeration it = role.getProperties().keys(); it.hasMoreElements();) { - String key = it.nextElement(); - if (key.equalsIgnoreCase(LdapAttrs.objectClass.name())) { - String[] objectClasses = role.getProperties().get(key).toString().split("\\n"); - objectClasses: for (String objectClass : objectClasses) { - if (LdapObjs.top.name().equalsIgnoreCase(objectClass)) - continue objectClasses; - contentClasses.add(new ContentName(CrName.LDAP_NAMESPACE_URI, objectClass, provider)); - } - break keys; - } + String objectClass = role.getProperties().get(LdapAttrs.objectClass.name()).toString(); + contentClasses.add(new ContentName(CrName.LDAP_NAMESPACE_URI, objectClass, provider)); + + String[] objectClasses = role.getProperties().get(LdapAttrs.objectClasses.name()).toString().split("\\n"); + objectClasses: for (String oc : objectClasses) { + if (LdapObjs.top.name().equalsIgnoreCase(oc)) + continue objectClasses; + if (objectClass.equalsIgnoreCase(oc)) + continue objectClasses; + contentClasses.add(new ContentName(CrName.LDAP_NAMESPACE_URI, oc, provider)); } return contentClasses; } diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java index 552bfdc8d..1eb4067d7 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java @@ -243,21 +243,23 @@ class LdifUser implements DirectoryUser { private final List attrFilter; private final Boolean includeFilter; - public AttributeDictionary(Boolean includeFilter) { + public AttributeDictionary(Boolean credentials) { this.attrFilter = userAdmin.getCredentialAttributeIds(); - this.includeFilter = includeFilter; + this.includeFilter = credentials; try { NamingEnumeration ids = getAttributes().getIDs(); while (ids.hasMore()) { String id = ids.next(); - if (includeFilter && attrFilter.contains(id)) + if (credentials && attrFilter.contains(id)) effectiveKeys.add(id); - else if (!includeFilter && !attrFilter.contains(id)) + else if (!credentials && !attrFilter.contains(id)) effectiveKeys.add(id); } } catch (NamingException e) { throw new UserDirectoryException("Cannot initialise attribute dictionary", e); } + if (!credentials) + effectiveKeys.add(LdapAttrs.objectClasses.name()); } @Override @@ -297,7 +299,8 @@ class LdifUser implements DirectoryUser { @Override public Object get(Object key) { try { - Attribute attr = getAttributes().get(key.toString()); + Attribute attr = !key.equals(LdapAttrs.objectClasses.name()) ? getAttributes().get(key.toString()) + : getAttributes().get(LdapAttrs.objectClass.name()); if (attr == null) return null; Object value = attr.get(); @@ -310,7 +313,7 @@ class LdifUser implements DirectoryUser { if (attr.size() == 1) return value; // special case for object class - if (attr.getID().equals(LdapAttrs.objectClass.name())) { + if (key.equals(LdapAttrs.objectClass.name())) { // TODO support multiple object classes NamingEnumeration en = attr.getAll(); String first = null;