X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Facr%2Ffs%2FFsContent.java;h=078cb50a8d38f28280385b7bf9e90f48c2c5aada;hb=eb4cc3db3bf141c229f0f7ff929daff108bee6d2;hp=bfcd0118d76e6348fff11911cf71821dec183425;hpb=7d2a002f5dcfe8a8c7b29803b70d4b1aff265ed1;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java b/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java index bfcd0118d..078cb50a8 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java @@ -1,6 +1,9 @@ package org.argeo.cms.acr.fs; +import java.io.Closeable; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -22,13 +25,16 @@ import org.argeo.api.acr.Content; import org.argeo.api.acr.ContentName; import org.argeo.api.acr.ContentResourceException; import org.argeo.api.acr.CrName; -import org.argeo.api.acr.spi.AbstractContent; +import org.argeo.api.acr.NamespaceUtils; +import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.cms.acr.AbstractContent; +import org.argeo.cms.acr.ContentUtils; import org.argeo.util.FsUtils; public class FsContent extends AbstractContent implements ProvidedContent { - private final static String USER_ = "user:"; + final static String USER_ = "user:"; private static final Map BASIC_KEYS; private static final Map POSIX_KEYS; @@ -57,10 +63,18 @@ public class FsContent extends AbstractContent implements ProvidedContent { this.path = path; this.isRoot = contentProvider.isRoot(path); // TODO check file names with ':' ? - if (isRoot) - this.name = CrName.ROOT.get(); - else - this.name = session.parsePrefixedName(path.getFileName().toString()); + if (isRoot) { + String mountPath = provider.getMountPath(); + if (mountPath != null && !mountPath.equals("/")) { + Content mountPoint = session.getMountPoint(mountPath); + this.name = mountPoint.getName(); + } else { + this.name = CrName.ROOT.get(); + } + } else { + QName providerName = NamespaceUtils.parsePrefixedName(provider, path.getFileName().toString()); + this.name = new ContentName(providerName, session); + } } protected FsContent(FsContent context, Path path) { @@ -85,7 +99,26 @@ public class FsContent extends AbstractContent implements ProvidedContent { Object value; try { // We need to add user: when accessing via Files#getAttribute - value = Files.getAttribute(path, toFsAttributeKey(key)); + + if (POSIX_KEYS.containsKey(key)) { + value = Files.getAttribute(path, toFsAttributeKey(key)); + } else { + UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, + UserDefinedFileAttributeView.class); + String prefixedName = NamespaceUtils.toPrefixedName(provider, key); + if (!udfav.list().contains(prefixedName)) + return Optional.empty(); + ByteBuffer buf = ByteBuffer.allocate(udfav.size(prefixedName)); + udfav.read(prefixedName, buf); + buf.flip(); + if (buf.hasArray()) + value = buf.array(); + else { + byte[] arr = new byte[buf.remaining()]; + buf.get(arr); + value = arr; + } + } } catch (IOException e) { throw new ContentResourceException("Cannot retrieve attribute " + key + " for " + path, e); } @@ -118,7 +151,9 @@ public class FsContent extends AbstractContent implements ProvidedContent { if (udfav != null) { try { for (String name : udfav.list()) { - result.add(session.parsePrefixedName(name)); + QName providerName = NamespaceUtils.parsePrefixedName(provider, name); + QName sessionName = new ContentName(providerName, session); + result.add(sessionName); } } catch (IOException e) { throw new ContentResourceException("Cannot list attributes for " + path, e); @@ -131,7 +166,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { protected void removeAttr(QName key) { UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class); try { - udfav.delete(session.toPrefixedName(key)); + udfav.delete(NamespaceUtils.toPrefixedName(provider, key)); } catch (IOException e) { throw new ContentResourceException("Cannot delete attribute " + key + " for " + path, e); } @@ -143,7 +178,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class); ByteBuffer bb = ByteBuffer.wrap(value.toString().getBytes(StandardCharsets.UTF_8)); try { - int size = udfav.write(session.toPrefixedName(key), bb); + int size = udfav.write(NamespaceUtils.toPrefixedName(provider, key), bb); } catch (IOException e) { throw new ContentResourceException("Cannot delete attribute " + key + " for " + path, e); } @@ -154,7 +189,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { if (POSIX_KEYS.containsKey(key)) return POSIX_KEYS.get(key); else - return USER_ + session.toPrefixedName(key); + return USER_ + NamespaceUtils.toPrefixedName(provider, key); } /* @@ -164,7 +199,19 @@ public class FsContent extends AbstractContent implements ProvidedContent { public Iterator iterator() { if (Files.isDirectory(path)) { try { - return Files.list(path).map((p) -> (Content) new FsContent(this, p)).iterator(); + return Files.list(path).map((p) -> { + FsContent fsContent = new FsContent(this, p); + Optional isMount = fsContent.get(CrName.MOUNT.get(), String.class); + if (isMount.orElse("false").equals("true")) { + QName[] classes = null; + ContentProvider contentProvider = session.getRepository().getMountContentProvider(fsContent, + false, classes); + Content mountedContent = contentProvider.get(session, fsContent.getPath(), ""); + return mountedContent; + } else { + return (Content) fsContent; + } + }).iterator(); } catch (IOException e) { throw new ContentResourceException("Cannot list " + path, e); } @@ -175,8 +222,9 @@ public class FsContent extends AbstractContent implements ProvidedContent { @Override public Content add(QName name, QName... classes) { + FsContent fsContent; try { - Path newPath = path.resolve(session.toPrefixedName(name)); + Path newPath = path.resolve(NamespaceUtils.toPrefixedName(provider, name)); if (ContentName.contains(classes, CrName.COLLECTION.get())) Files.createDirectory(newPath); else @@ -185,10 +233,20 @@ public class FsContent extends AbstractContent implements ProvidedContent { // for(ContentClass clss:classes) { // Files.setAttribute(newPath, name, newPath, null) // } - return new FsContent(this, newPath); + fsContent = new FsContent(this, newPath); } catch (IOException e) { throw new ContentResourceException("Cannot create new content", e); } + + if (session.getRepository().shouldMount(classes)) { + ContentProvider contentProvider = session.getRepository().getMountContentProvider(fsContent, true, classes); + Content mountedContent = contentProvider.get(session, fsContent.getPath(), ""); + fsContent.put(CrName.MOUNT.get(), "true"); + return mountedContent; + + } else { + return fsContent; + } } @Override @@ -198,11 +256,40 @@ public class FsContent extends AbstractContent implements ProvidedContent { @Override public Content getParent() { - if (isRoot) - return null;// TODO deal with mounts + if (isRoot) { + String mountPath = provider.getMountPath(); + if (mountPath == null || mountPath.equals("/")) + return null; + String[] parent = ContentUtils.getParentPath(mountPath); + return session.get(parent[0]); + } return new FsContent(this, path.getParent()); } + @Override + public C open(Class clss) throws IOException, IllegalArgumentException { + if (InputStream.class.isAssignableFrom(clss)) { + if (Files.isDirectory(path)) + throw new UnsupportedOperationException("Cannot open " + path + " as stream, since it is a directory"); + return (C) Files.newInputStream(path); + } else if (OutputStream.class.isAssignableFrom(clss)) { + if (Files.isDirectory(path)) + throw new UnsupportedOperationException("Cannot open " + path + " as stream, since it is a directory"); + return (C) Files.newOutputStream(path); + } + return super.open(clss); + } + + /* + * MOUNT MANAGEMENT + */ + @Override + public ProvidedContent getMountPoint(String relativePath) { + Path childPath = path.resolve(relativePath); + // TODO check that it is a mount + return new FsContent(this, childPath); + } + /* * ACCESSORS */