From eb8ade17be22103b314bf664e999185641fdcde0 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Mon, 23 Oct 2023 06:59:01 +0200 Subject: [PATCH] Improve CMS file system --- .../argeo/cms/file/provider/CmsFileStore.java | 4 +- .../cms/file/provider/CmsFileSystem.java | 2 +- .../file/provider/CmsFileSystemProvider.java | 21 +++-- .../file/provider/ContentAttributeView.java | 24 ------ .../cms/file/provider/ContentAttributes.java | 80 ++++++++++++++++++ .../file/provider/ContentDirectoryStream.java | 15 +--- .../provider/ContentFileAttributeView.java | 83 +++++++++++++++++++ .../src/org/argeo/cms/swt/app/CmsUserApp.java | 2 +- 8 files changed, 183 insertions(+), 48 deletions(-) delete mode 100644 org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java create mode 100644 org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributes.java create mode 100644 org.argeo.cms/src/org/argeo/cms/file/provider/ContentFileAttributeView.java diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileStore.java b/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileStore.java index 7abeec4e6..31fe9c73c 100644 --- a/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileStore.java +++ b/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileStore.java @@ -52,14 +52,14 @@ public class CmsFileStore extends AbstractFsStore { @Override public boolean supportsFileAttributeView(Class type) { - if (ContentAttributeView.class.isAssignableFrom(type)) + if (ContentFileAttributeView.class.isAssignableFrom(type)) return true; return false; } @Override public boolean supportsFileAttributeView(String name) { - if (ContentAttributeView.NAME.equals(name)) + if (ContentFileAttributeView.NAME.equals(name)) return true; return false; } diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystem.java b/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystem.java index f581ea1c4..0b5d5defe 100644 --- a/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystem.java +++ b/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystem.java @@ -87,7 +87,7 @@ public class CmsFileSystem extends AbstractFsSystem { @Override public Set supportedFileAttributeViews() { - return Collections.singleton(ContentAttributeView.NAME); + return Collections.singleton(ContentFileAttributeView.NAME); } @Override diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystemProvider.java b/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystemProvider.java index 5d93b7b58..602441e2f 100644 --- a/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystemProvider.java +++ b/org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystemProvider.java @@ -39,15 +39,14 @@ public class CmsFileSystemProvider extends FileSystemProvider { private ProvidedRepository contentRepository; - public void start() { - + } - + public void stop() { - + } - + @Override public String getScheme() { return "cms"; @@ -171,17 +170,23 @@ public class CmsFileSystemProvider extends FileSystemProvider { public void checkAccess(Path path, AccessMode... modes) throws IOException { } + @SuppressWarnings("unchecked") @Override public V getFileAttributeView(Path path, Class type, LinkOption... options) { - // TODO Auto-generated method stub + CmsPath cmsPath = (CmsPath) path; + if (BasicFileAttributes.class.isAssignableFrom(type)) + return (V) new ContentFileAttributeView(cmsPath.getContent()); + else if (ContentFileAttributeView.class.isAssignableFrom(type)) + return (V) new ContentFileAttributeView(cmsPath.getContent()); return null; } + @SuppressWarnings("unchecked") @Override public A readAttributes(Path path, Class type, LinkOption... options) throws IOException { - // TODO Auto-generated method stub - return null; + CmsPath cmsPath = (CmsPath) path; + return (A) new ContentAttributes(cmsPath.getContent()); } @Override diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java deleted file mode 100644 index 9bce0424a..000000000 --- a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.argeo.cms.file.provider; - -import java.nio.file.attribute.FileAttributeView; - -import org.argeo.api.acr.Content; - -public class ContentAttributeView implements FileAttributeView { - final static String NAME = "content"; - - private final Content content; - - public ContentAttributeView(Content content) { - this.content = content; - } - - @Override - public String name() { - return NAME; - } - - public Content getContent() { - return content; - } -} diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributes.java b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributes.java new file mode 100644 index 000000000..827bb2a76 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributes.java @@ -0,0 +1,80 @@ +package org.argeo.cms.file.provider; + +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.time.Instant; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.DName; + +public class ContentAttributes implements BasicFileAttributes { + // TODO optimise for FS-based content + private final Content content; + + public ContentAttributes(Content content) { + assert content != null; + this.content = content; + } + + @Override + public FileTime lastModifiedTime() { + Instant t = content.get(DName.getlastmodified, Instant.class).orElseThrow(); + return FileTime.from(t); + } + + @Override + public FileTime lastAccessTime() { + // TODO implement the concept in ACR ? + return FileTime.fromMillis(0l); + } + + @Override + public FileTime creationTime() { + Instant t = content.get(DName.getlastmodified, Instant.class).orElseThrow(); + return FileTime.from(t); + } + + @Override + public boolean isRegularFile() { + return isRegularFile(content); + } + + @Override + public boolean isDirectory() { + return isDirectory(content); + } + + @Override + public boolean isSymbolicLink() { + // TODO supports links in ACR + return false; + } + + @Override + public boolean isOther() { + return !isDirectory() && !isRegularFile() && !isSymbolicLink(); + } + + @Override + public long size() { + long size = content.get(DName.getcontentlength, Long.class).orElse(-1l); + return size; + } + + @Override + public Object fileKey() { + // TODO check for UUIDs, etc. + return null; + } + + static boolean isDirectory(Content c) { + return !isRegularFile(c); +// return c.isContentClass(DName.collection); + } + + static boolean isRegularFile(Content c) { +// return c.containsKey(DName.getcontenttype.qName()); + return !c.get(DName.getcontenttype, String.class).isEmpty(); + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java index 2cddf6275..55db44360 100644 --- a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java +++ b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java @@ -7,7 +7,6 @@ import java.nio.file.Path; import java.util.Iterator; import org.argeo.api.acr.Content; -import org.argeo.api.acr.DName; public class ContentDirectoryStream implements DirectoryStream { private final CmsPath dir; @@ -31,21 +30,13 @@ public class ContentDirectoryStream implements DirectoryStream { return iterator; } - static boolean isFile(Content c) { - return !c.get(DName.getcontenttype, String.class).isEmpty(); - } - - static boolean isDirectory(Content c) { - return c.isContentClass(DName.collection); - } - class FilesAndCollectionsIterator implements Iterator { private Content next; private final Iterator it; public FilesAndCollectionsIterator() { Content content = dir.getContent(); - if (!content.isContentClass(DName.collection)) + if (!ContentAttributes.isDirectory(content)) throw new IllegalStateException("Content " + content + " is not a collection"); it = content.iterator(); findNext(); @@ -53,9 +44,9 @@ public class ContentDirectoryStream implements DirectoryStream { private void findNext() { next = null; - while (it.hasNext() && next != null) { + while (it.hasNext() && next == null) { Content n = it.next(); - if (isFile(n) || isDirectory(n)) { + if (ContentAttributes.isRegularFile(n) || ContentAttributes.isDirectory(n)) { if (filter != null) { try { if (filter.accept(new CmsPath(dir.getFileSystem(), n))) diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentFileAttributeView.java b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentFileAttributeView.java new file mode 100644 index 000000000..adbe8d079 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentFileAttributeView.java @@ -0,0 +1,83 @@ +package org.argeo.cms.file.provider; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.UserDefinedFileAttributeView; +import java.util.List; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.DName; + +public class ContentFileAttributeView implements BasicFileAttributeView, UserDefinedFileAttributeView { + final static String NAME = "content"; + + private final Content content; + + public ContentFileAttributeView(Content content) { + this.content = content; + } + + @Override + public String name() { + return NAME; + } + + /* + * BasicFileAttributeView + */ + + @Override + public BasicFileAttributes readAttributes() throws IOException { + return new ContentAttributes(content); + } + + @Override + public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException { + if (lastModifiedTime != null) + content.put(DName.getlastmodified, lastModifiedTime.toInstant()); + if (createTime != null) + content.put(DName.getlastmodified, createTime.toInstant()); + // ignore last accessed time + } + + /* + * UserDefinedFileAttributeView + */ + + @Override + public List list() throws IOException { +// List res = new ArrayList<>(); + return null; + } + + @Override + public int size(String name) throws IOException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int read(String name, ByteBuffer dst) throws IOException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int write(String name, ByteBuffer src) throws IOException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void delete(String name) throws IOException { + // TODO Auto-generated method stub + + } + + public Content getContent() { + return content; + } +} diff --git a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java b/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java index d8d0f3043..ca98f69be 100644 --- a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java +++ b/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java @@ -48,7 +48,7 @@ public class CmsUserApp extends AbstractCmsApp { } else if ("app".equals(uiName)) { Path rootPath = cmsFileSystemProvider.getPath(URI.create("cms:///")); - SimpleFsBrowser view = new SimpleFsBrowser(parent, 0); + SimpleFsBrowser view = new SimpleFsBrowser(cmsUi, 0); view.setInput(rootPath); view.setLayoutData(CmsSwtUtils.fillAll()); -- 2.30.2