From 59ba52ac31cac753961fe9e2e55bbae21735ea96 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 15 Jun 2023 10:33:56 +0200 Subject: [PATCH] Introduce terms content provider --- .../src/org/argeo/app/api/EntityType.java | 21 ++---- .../src/org/argeo/app/api/TermsManager.java | 5 +- .../OSGI-INF/termsContentProvider.xml | 9 +++ org.argeo.app.core/bnd.bnd | 1 + org.argeo.app.core/build.properties | 3 +- .../org/argeo/app/acr/terms/TermContent.java | 46 +++++++++++++ .../app/acr/terms/TermsContentProvider.java | 69 +++++++++++++++++++ .../argeo/app/acr/terms/TypologyContent.java | 45 ++++++++++++ .../app/jcr/terms/SuiteTermsManager.java | 14 ++++ .../OSGI-INF/termsEntryArea.xml | 1 + .../argeo/app/swt/terms/TermsEntryArea.java | 58 ++++++++++++++-- 11 files changed, 249 insertions(+), 23 deletions(-) create mode 100644 org.argeo.app.core/OSGI-INF/termsContentProvider.xml create mode 100644 org.argeo.app.core/src/org/argeo/app/acr/terms/TermContent.java create mode 100644 org.argeo.app.core/src/org/argeo/app/acr/terms/TermsContentProvider.java create mode 100644 org.argeo.app.core/src/org/argeo/app/acr/terms/TypologyContent.java diff --git a/org.argeo.app.api/src/org/argeo/app/api/EntityType.java b/org.argeo.app.api/src/org/argeo/app/api/EntityType.java index 8b9164a..1e30821 100644 --- a/org.argeo.app.api/src/org/argeo/app/api/EntityType.java +++ b/org.argeo.app.api/src/org/argeo/app/api/EntityType.java @@ -19,31 +19,20 @@ public enum EntityType implements QNamed { // ldap person, user; + public final static String ENTITY_NAMESPACE_URI = "http://www.argeo.org/ns/entity"; + public final static String ENTITY_DEFAULT_PREFIX = "entity"; + @Override public String getDefaultPrefix() { - return "entity"; + return ENTITY_DEFAULT_PREFIX; } -// @Override -// public String getPrefix() { -// return getDefaultPrefix(); -// } -// -// public static String prefix() { -// return "entity"; -// } - public String basePath() { return '/' + name(); } @Override public String getNamespace() { - return "http://www.argeo.org/ns/entity"; + return ENTITY_NAMESPACE_URI; } - -// public static String namespace() { -// return "http://www.argeo.org/ns/entity"; -// } - } diff --git a/org.argeo.app.api/src/org/argeo/app/api/TermsManager.java b/org.argeo.app.api/src/org/argeo/app/api/TermsManager.java index decddd9..03e1150 100644 --- a/org.argeo.app.api/src/org/argeo/app/api/TermsManager.java +++ b/org.argeo.app.api/src/org/argeo/app/api/TermsManager.java @@ -1,11 +1,14 @@ package org.argeo.app.api; import java.util.List; +import java.util.Set; /** Provides optimised access and utilities around terms typologies. */ public interface TermsManager { Typology getTypology(String typology); - + + Set getTypologies(); + Term getTerm(String id); List listAllTerms(String typology); diff --git a/org.argeo.app.core/OSGI-INF/termsContentProvider.xml b/org.argeo.app.core/OSGI-INF/termsContentProvider.xml new file mode 100644 index 0000000..4d5a1d2 --- /dev/null +++ b/org.argeo.app.core/OSGI-INF/termsContentProvider.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.app.core/bnd.bnd b/org.argeo.app.core/bnd.bnd index 7a92b9b..c07e947 100644 --- a/org.argeo.app.core/bnd.bnd +++ b/org.argeo.app.core/bnd.bnd @@ -2,6 +2,7 @@ Bundle-ActivationPolicy: lazy Service-Component:\ OSGI-INF/suiteMaintenance.xml,\ +OSGI-INF/termsContentProvider.xml,\ Import-Package:\ tech.units.indriya.unit,\ diff --git a/org.argeo.app.core/build.properties b/org.argeo.app.core/build.properties index 4974d56..741e843 100644 --- a/org.argeo.app.core/build.properties +++ b/org.argeo.app.core/build.properties @@ -2,7 +2,8 @@ bin.includes = META-INF/,\ .,\ OSGI-INF/,\ OSGI-INF/appUserState.xml,\ - OSGI-INF/suiteMaintenance.xml + OSGI-INF/suiteMaintenance.xml,\ + OSGI-INF/termsContentProvider.xml additional.bundles = org.argeo.init source.. = src/ output.. = bin/ diff --git a/org.argeo.app.core/src/org/argeo/app/acr/terms/TermContent.java b/org.argeo.app.core/src/org/argeo/app/acr/terms/TermContent.java new file mode 100644 index 0000000..672f66f --- /dev/null +++ b/org.argeo.app.core/src/org/argeo/app/acr/terms/TermContent.java @@ -0,0 +1,46 @@ +package org.argeo.app.acr.terms; + +import java.util.Iterator; + +import javax.xml.namespace.QName; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.NamespaceUtils; +import org.argeo.api.acr.spi.ContentProvider; +import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.app.api.Term; +import org.argeo.cms.acr.AbstractContent; + +public class TermContent extends AbstractContent { + private TermsContentProvider provider; + private Term term; + + public TermContent(ProvidedSession session, TermsContentProvider provider, Term term) { + super(session); + this.provider = provider; + this.term = term; + } + + @Override + public Iterator iterator() { + return term.getSubTerms().stream().map((t) -> (Content) new TermContent(getSession(), provider, t)).iterator(); + } + + @Override + public ContentProvider getProvider() { + return provider; + } + + @Override + public QName getName() { + return NamespaceUtils.unqualified(term.getName()); + } + + @Override + public Content getParent() { + Term parentTerm = term.getParentTerm(); + return parentTerm == null ? new TypologyContent(getSession(), provider, term.getTypology()) + : new TermContent(getSession(), provider, parentTerm); + } + +} diff --git a/org.argeo.app.core/src/org/argeo/app/acr/terms/TermsContentProvider.java b/org.argeo.app.core/src/org/argeo/app/acr/terms/TermsContentProvider.java new file mode 100644 index 0000000..2d7a5d1 --- /dev/null +++ b/org.argeo.app.core/src/org/argeo/app/acr/terms/TermsContentProvider.java @@ -0,0 +1,69 @@ +package org.argeo.app.acr.terms; + +import java.util.Iterator; +import java.util.List; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.ContentNotFoundException; +import org.argeo.api.acr.spi.ProvidedContent; +import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.app.api.EntityType; +import org.argeo.app.api.Term; +import org.argeo.app.api.TermsManager; +import org.argeo.app.api.Typology; +import org.argeo.cms.acr.AbstractSimpleContentProvider; +import org.argeo.cms.acr.ContentUtils; + +public class TermsContentProvider extends AbstractSimpleContentProvider { + + public TermsContentProvider() { + super(EntityType.ENTITY_NAMESPACE_URI, EntityType.ENTITY_DEFAULT_PREFIX); + } + + @Override + protected Iterator firstLevel(ProvidedSession session) { + return getService().getTypologies().stream().map((t) -> (Content) new TypologyContent(session, this, t)) + .iterator(); + } + + @Override + public ProvidedContent get(ProvidedSession session, List segments) { + String typologyName = segments.get(0); + Typology typology = getService().getTypology(typologyName); + if (segments.size() == 1) + return new TypologyContent(session, this, typology); + Term currTerm = null; + terms: for (Term term : typology.getSubTerms()) { + if (term.getName().equals(segments.get(1))) { + currTerm = term; + break terms; + } + } + if (currTerm == null) + throw new ContentNotFoundException(session, + getMountPath() + "/" + ContentUtils.toPath(segments) + " cannot be found"); + if (segments.size() == 1) + return new TermContent(session, this, currTerm); + + for (int i = 2; i < segments.size(); i++) { + String termName = segments.get(i); + Term nextTerm = null; + terms: for (Term term : currTerm.getSubTerms()) { + if (term.getName().equals(termName)) { + nextTerm = term; + break terms; + } + } + if (nextTerm == null) + throw new ContentNotFoundException(session, + getMountPath() + "/" + ContentUtils.toPath(segments) + " cannot be found"); + currTerm = nextTerm; + } + return new TermContent(session, this, currTerm); + } + + ServiceContent getRootContent(ProvidedSession session) { + return new ServiceContent(session); + } + +} diff --git a/org.argeo.app.core/src/org/argeo/app/acr/terms/TypologyContent.java b/org.argeo.app.core/src/org/argeo/app/acr/terms/TypologyContent.java new file mode 100644 index 0000000..63bb8a3 --- /dev/null +++ b/org.argeo.app.core/src/org/argeo/app/acr/terms/TypologyContent.java @@ -0,0 +1,45 @@ +package org.argeo.app.acr.terms; + +import java.util.Iterator; + +import javax.xml.namespace.QName; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.NamespaceUtils; +import org.argeo.api.acr.spi.ContentProvider; +import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.app.api.Typology; +import org.argeo.cms.acr.AbstractContent; + +public class TypologyContent extends AbstractContent { + private TermsContentProvider provider; + private Typology typology; + + public TypologyContent(ProvidedSession session, TermsContentProvider provider, Typology typology) { + super(session); + this.provider = provider; + this.typology = typology; + } + + @Override + public ContentProvider getProvider() { + return provider; + } + + @Override + public QName getName() { + return NamespaceUtils.unqualified(typology.getId()); + } + + @Override + public Content getParent() { + return provider.getRootContent(getSession()); + } + + @Override + public Iterator iterator() { + return typology.getSubTerms().stream().map((t) -> (Content) new TermContent(getSession(), provider, t)) + .iterator(); + } + +} diff --git a/org.argeo.app.jcr/src/org/argeo/app/jcr/terms/SuiteTermsManager.java b/org.argeo.app.jcr/src/org/argeo/app/jcr/terms/SuiteTermsManager.java index 6327a55..eba0529 100644 --- a/org.argeo.app.jcr/src/org/argeo/app/jcr/terms/SuiteTermsManager.java +++ b/org.argeo.app.jcr/src/org/argeo/app/jcr/terms/SuiteTermsManager.java @@ -4,8 +4,11 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import javax.jcr.Node; +import javax.jcr.NodeIterator; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -15,6 +18,7 @@ import org.argeo.app.api.EntityNames; import org.argeo.app.api.EntityType; import org.argeo.app.api.Term; import org.argeo.app.api.TermsManager; +import org.argeo.app.api.Typology; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; @@ -60,6 +64,16 @@ public class SuiteTermsManager implements TermsManager { return t; } + @Override + public Set getTypologies() { + Set res = new TreeSet<>((o1, o2) -> o1.getId().compareTo(o2.getId())); + NodeIterator termsNodes = Jcr.executeQuery(adminSession, "SELECT * FROM [{0}]", EntityType.terms.get()); + for (Node termsNode : Jcr.iterate(termsNodes)) { + res.add(loadTypology(termsNode)); + } + return res; + } + SuiteTypology loadTypology(Node termsNode) { try { SuiteTypology typology = new SuiteTypology(termsNode); diff --git a/org.argeo.product.knowledge/OSGI-INF/termsEntryArea.xml b/org.argeo.product.knowledge/OSGI-INF/termsEntryArea.xml index e241b11..404ebc3 100644 --- a/org.argeo.product.knowledge/OSGI-INF/termsEntryArea.xml +++ b/org.argeo.product.knowledge/OSGI-INF/termsEntryArea.xml @@ -6,4 +6,5 @@ + diff --git a/swt/org.argeo.app.swt/src/org/argeo/app/swt/terms/TermsEntryArea.java b/swt/org.argeo.app.swt/src/org/argeo/app/swt/terms/TermsEntryArea.java index 2193a3c..7ae2531 100644 --- a/swt/org.argeo.app.swt/src/org/argeo/app/swt/terms/TermsEntryArea.java +++ b/swt/org.argeo.app.swt/src/org/argeo/app/swt/terms/TermsEntryArea.java @@ -1,22 +1,70 @@ package org.argeo.app.swt.terms; import org.argeo.api.acr.Content; +import org.argeo.api.acr.NamespaceUtils; +import org.argeo.api.acr.spi.ProvidedContent; +import org.argeo.api.cms.ux.CmsView; +import org.argeo.app.api.EntityType; +import org.argeo.app.api.TermsManager; +import org.argeo.app.ux.SuiteUxEvent; +import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.swt.acr.SwtUiProvider; -import org.eclipse.swt.SWT; +import org.argeo.cms.swt.widgets.SwtTreeView; +import org.argeo.cms.ux.acr.ContentHierarchicalPart; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; /** Entry area for managing the typologies. */ public class TermsEntryArea implements SwtUiProvider { + private TermsManager termsManager; @Override public Control createUiPart(Composite parent, Content content) { +// parent.setLayout(new GridLayout()); +// Label lbl = new Label(parent, SWT.NONE); +// lbl.setText("Typologies"); +// +// Set typologies = termsManager.getTypologies(); +// for (Typology typology : typologies) { +// new Label(parent, 0).setText(typology.getId()); +// } +// +// +// return lbl; + CmsView cmsView = CmsSwtUtils.getCmsView(parent); + parent.setLayout(new GridLayout()); - Label lbl = new Label(parent, SWT.NONE); - lbl.setText("Typologies"); - return lbl; + Content rootContent = ((ProvidedContent) content).getSession().getRepository().get().get("/terms"); + + ContentHierarchicalPart contentPart = new ContentHierarchicalPart() { + + @Override + protected boolean isLeaf(Content content) { + if (content.hasContentClass(EntityType.document.qName())) + return true; + return super.isLeaf(content); + } + + }; + contentPart.addColumn((c) -> NamespaceUtils.toPrefixedName(c.getName())); + contentPart.setInput(rootContent); + + SwtTreeView view = new SwtTreeView<>(parent, 0, contentPart); + view.setLayoutData(CmsSwtUtils.fillAll()); + + contentPart.setInput(rootContent); +// contentPart.onSelected((o) -> { +// Content c = (Content) o; +//// log.debug(c.getPath()); +// cmsView.sendEvent(SuiteUxEvent.refreshPart.topic(), SuiteUxEvent.eventProperties(c)); +// }); + return view; + + } + + public void setTermsManager(TermsManager termsManager) { + this.termsManager = termsManager; } } -- 2.30.2