From 85015a7cbfe5343c88477d828fa2f8fb754a65cd Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 24 May 2022 08:05:41 +0200 Subject: [PATCH] Improve namespace management --- .../argeo/cms/acr/CmsContentRepository.java | 17 +++++++++-------- .../argeo/cms/acr/fs/FsContentProvider.java | 15 ++++++++++++++- .../src/org/argeo/cms/acr/xml/DomContent.java | 11 ++++++----- .../argeo/cms/acr/xml/DomContentProvider.java | 16 ++++++++-------- .../src/org/argeo/cms/auth/CmsAuthUtils.java | 18 +++++++++--------- .../cms/internal/runtime/CmsContextImpl.java | 8 ++++++++ 6 files changed, 54 insertions(+), 31 deletions(-) diff --git a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentRepository.java b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentRepository.java index 923142c82..b1f715ae3 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentRepository.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentRepository.java @@ -11,7 +11,6 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.NavigableMap; -import java.util.Set; import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -29,7 +28,6 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import javax.xml.validation.Schema; import org.argeo.api.acr.Content; import org.argeo.api.acr.ContentSession; @@ -64,7 +62,7 @@ public class CmsContentRepository implements ProvidedRepository { // TODO synchronize ? private NavigableMap prefixes = new TreeMap<>(); - private Schema schema; +// private Schema schema; private CmsContentSession systemSession; @@ -176,7 +174,7 @@ public class CmsContentRepository implements ProvidedRepository { }); Document document; - if (Files.exists(path)) { + if (path != null && Files.exists(path)) { InputSource inputSource = new InputSource(path.toAbsolutePath().toUri().toString()); inputSource.setEncoding(StandardCharsets.UTF_8.name()); // TODO public id as well? @@ -194,10 +192,11 @@ public class CmsContentRepository implements ProvidedRepository { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(document); - try (Writer writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) { - StreamResult result = new StreamResult(writer); - transformer.transform(source, result); - } + if (path != null) + try (Writer writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) { + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + } } DomContentProvider contentProvider = new DomContentProvider(document); @@ -240,6 +239,8 @@ public class CmsContentRepository implements ProvidedRepository { @Override public Content get(String path) { Map.Entry entry = partitions.floorEntry(path); + if (entry == null) + throw new IllegalArgumentException("No entry provider found for " + path); String mountPath = entry.getKey(); ContentProvider provider = entry.getValue(); String relativePath = path.substring(mountPath.length()); diff --git a/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContentProvider.java b/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContentProvider.java index 65bdd343e..37401a29c 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContentProvider.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContentProvider.java @@ -64,11 +64,24 @@ public class FsContentProvider implements ContentProvider { throws IOException { if (!prefixes.containsKey(prefix)) { ByteBuffer bb = ByteBuffer.wrap(namespace.getBytes(StandardCharsets.UTF_8)); - int size = udfav.write(XMLNS_ + prefix, bb); + udfav.write(XMLNS_ + prefix, bb); prefixes.put(prefix, namespace); } } + public void registerPrefix(String prefix, String namespace) { + if (prefixes.containsKey(prefix)) + prefixes.remove(prefix); + try { + UserDefinedFileAttributeView udfav = Files.getFileAttributeView(rootPath, + UserDefinedFileAttributeView.class); + addDefaultNamespace(udfav, prefix, namespace); + } catch (IOException e) { + throw new RuntimeException("Cannot register namespace " + prefix + " " + namespace + " on " + rootPath, e); + } + + } + boolean isRoot(Path path) { try { return isRoot && Files.isSameFile(rootPath, path); diff --git a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java index 5cb458362..9e370db0c 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java @@ -55,27 +55,27 @@ public class DomContent extends AbstractContent implements ProvidedContent { if (namespaceURI == null) { return toQName(node, node.getLocalName()); } else { - String contextPrefix = session.getPrefix(namespaceURI); + String contextPrefix = provider.getPrefix(namespaceURI); if (contextPrefix == null) throw new IllegalStateException("Namespace " + namespaceURI + " is unbound"); - return toQName(node, namespaceURI, node.getLocalName(), session); + return toQName(node, namespaceURI, node.getLocalName(), provider); } } else { String namespaceURI = node.getNamespaceURI(); if (namespaceURI == null) namespaceURI = node.getOwnerDocument().lookupNamespaceURI(prefix); if (namespaceURI == null) { - namespaceURI = session.getNamespaceURI(prefix); + namespaceURI = provider.getNamespaceURI(prefix); if (XMLConstants.NULL_NS_URI.equals(namespaceURI)) throw new IllegalStateException("Prefix " + prefix + " is unbound"); // TODO bind the prefix in the document? } - return toQName(node, namespaceURI, node.getLocalName(), session); + return toQName(node, namespaceURI, node.getLocalName(), provider); } } protected QName toQName(Node source, String namespaceURI, String localName, NamespaceContext namespaceContext) { - return new ContentName(namespaceURI, localName, session); + return new ContentName(namespaceURI, localName, namespaceContext); } protected QName toQName(Node source, String localName) { @@ -98,6 +98,7 @@ public class DomContent extends AbstractContent implements ProvidedContent { return result; } + @SuppressWarnings("unchecked") @Override public Optional get(QName key, Class clss) { String namespaceUriOrNull = XMLConstants.NULL_NS_URI.equals(key.getNamespaceURI()) ? null diff --git a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContentProvider.java b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContentProvider.java index efca3effd..4db493433 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContentProvider.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContentProvider.java @@ -6,8 +6,6 @@ import java.util.Iterator; import java.util.List; import javax.xml.namespace.NamespaceContext; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; @@ -15,15 +13,12 @@ import javax.xml.xpath.XPathFactory; import org.argeo.api.acr.Content; import org.argeo.api.acr.ContentNotFoundException; -import org.argeo.api.acr.CrName; +import org.argeo.api.acr.NamespaceUtils; import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedSession; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; public class DomContentProvider implements ContentProvider, NamespaceContext { private Document document; @@ -41,7 +36,7 @@ public class DomContentProvider implements ContentProvider, NamespaceContext { @Override protected XPath initialValue() { // TODO set the document as namespace context? - XPath res= xPathFactory.newXPath(); + XPath res = xPathFactory.newXPath(); res.setNamespaceContext(DomContentProvider.this); return res; } @@ -87,11 +82,17 @@ public class DomContentProvider implements ContentProvider, NamespaceContext { */ @Override public String getNamespaceURI(String prefix) { + String namespaceURI = NamespaceUtils.getStandardNamespaceURI(prefix); + if (namespaceURI != null) + return namespaceURI; return document.lookupNamespaceURI(prefix); } @Override public String getPrefix(String namespaceURI) { + String prefix = NamespaceUtils.getStandardPrefix(namespaceURI); + if (prefix != null) + return prefix; return document.lookupPrefix(namespaceURI); } @@ -102,5 +103,4 @@ public class DomContentProvider implements ContentProvider, NamespaceContext { return Collections.unmodifiableList(res).iterator(); } - } diff --git a/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java b/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java index 46adcf8a5..4998c89ff 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java @@ -1,7 +1,6 @@ package org.argeo.cms.auth; import java.security.Principal; -import java.util.Collection; import java.util.Locale; import java.util.Set; import java.util.UUID; @@ -11,20 +10,16 @@ import javax.naming.ldap.LdapName; import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; -import org.argeo.api.cms.CmsSession; -import org.argeo.api.cms.CmsSessionId; -import org.argeo.api.cms.DataAdminPrincipal; import org.argeo.api.cms.AnonymousPrincipal; import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsSessionId; +import org.argeo.api.cms.DataAdminPrincipal; import org.argeo.cms.internal.auth.CmsSessionImpl; import org.argeo.cms.internal.auth.ImpliedByPrincipal; import org.argeo.cms.internal.http.WebCmsSessionImpl; import org.argeo.cms.internal.runtime.CmsContextImpl; import org.argeo.cms.security.NodeSecurityUtils; import org.argeo.osgi.useradmin.AuthenticatingUser; -import org.osgi.framework.BundleContext; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpContext; import org.osgi.service.useradmin.Authorization; @@ -44,6 +39,8 @@ class CmsAuthUtils { final static String SHARED_STATE_REMOTE_ADDR = "org.argeo.cms.auth.remote.addr"; final static String SHARED_STATE_REMOTE_PORT = "org.argeo.cms.auth.remote.port"; + final static String SINGLE_USER_LOCAL_ID = "single-user"; + static void addAuthorization(Subject subject, Authorization authorization) { assert subject != null; checkSubjectEmpty(subject); @@ -182,8 +179,11 @@ class CmsAuthUtils { "Subject already logged with session " + storedSessionId + " (not " + nodeSessionId + ")"); } } else { - CmsSessionImpl cmsSession = new CmsSessionImpl(subject, authorization, locale, "desktop"); - CmsContextImpl.getCmsContext().registerCmsSession(cmsSession); + CmsSessionImpl cmsSession = CmsContextImpl.getCmsContext().getCmsSessionByLocalId(SINGLE_USER_LOCAL_ID); + if (cmsSession == null) { + cmsSession = new CmsSessionImpl(subject, authorization, locale, SINGLE_USER_LOCAL_ID); + CmsContextImpl.getCmsContext().registerCmsSession(cmsSession); + } CmsSessionId nodeSessionId = new CmsSessionId(cmsSession.getUuid()); subject.getPrivateCredentials().add(nodeSessionId); } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java index ef9f0ec9a..93ed319f1 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java @@ -242,10 +242,18 @@ public class CmsContextImpl implements CmsContext { cmsSessionsByLocalId.remove(cmsSession.getLocalId()); } + /** + * The {@link CmsSession} related to this UUID, or null if not + * registered. + */ public synchronized CmsSessionImpl getCmsSessionByUuid(UUID uuid) { return cmsSessionsByUuid.get(uuid); } + /** + * The {@link CmsSession} related to this local id, or null if not + * registered. + */ public synchronized CmsSessionImpl getCmsSessionByLocalId(String localId) { return cmsSessionsByLocalId.get(localId); } -- 2.30.2