blob: 59111d38b0a7902516c1502bc311a4ee8ea850d2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.commons.jcr.file.internal;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.spi.FileSystemProvider;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.sling.commons.jcr.file.JcrFileSupportService;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(
service = FileSystemProvider.class,
property = {
Constants.SERVICE_DESCRIPTION + "=Apache Sling Commons JCR File System Provider",
Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
"type=jcr"
}
)
public class JcrFileSystemProvider extends FileSystemProvider {
private final Map<Session, JcrFileSystem> cache = new HashMap<>();
private final JcrFileStore jcrFileStore = new JcrFileStore();
@Reference
private volatile JcrFileSupportService jcrFileSupportService;
private final Object lock = new Object();
static final String SCHEME = "jcr";
private final Logger logger = LoggerFactory.getLogger(JcrFileSystemProvider.class);
public JcrFileSystemProvider() {
}
@Override
public String getScheme() {
logger.info("getting scheme");
return SCHEME;
}
@Override
public FileSystem newFileSystem(final URI uri, final Map<String, ?> env) throws IOException {
logger.info("new file system: {}, {}", uri, env);
if (!getScheme().equalsIgnoreCase(uri.getScheme())) {
throw new IllegalArgumentException("URI scheme is not " + getScheme());
}
if (env == null) {
throw new IllegalArgumentException("env is null");
}
if (!env.containsKey(Session.class.getName())) {
throw new IllegalArgumentException("no session in env");
}
final Object object = env.get(Session.class.getName());
if (object == null) {
throw new IllegalArgumentException("session in env is null");
}
if (!(object instanceof Session)) {
throw new IllegalArgumentException("session in env is not a " + Session.class.getName());
}
final Session session = (Session) object;
if (!session.isLive()) {
throw new IllegalArgumentException("session in env is not live");
}
synchronized (lock) {
if (isInCache(session)) {
throw new IllegalArgumentException("session is already in use");
}
final JcrFileSystem fileSystem = new JcrFileSystem(this, uri, session);
putIntoCache(fileSystem);
return fileSystem;
}
}
@Override
public FileSystem getFileSystem(final URI uri) {
final String message = String.format("getting file system by URI is not supported: %s", uri.toString());
logger.error(message);
throw new UnsupportedOperationException(message);
}
@Override
public Path getPath(final URI uri) {
final String message = String.format("getting path by URI is not supported: %s", uri.toString());
logger.error(message);
throw new UnsupportedOperationException(message);
}
// TODO
public FileChannel newFileChannel(final Path path, final Set<? extends OpenOption> options, final FileAttribute<?>... attrs) throws IOException {
logger.info("newFileChannel");
try {
final JcrPath jcrPath = (JcrPath) path;
final Node node;
if (jcrPath.toFile().exists()) {
node = PathUtil.toNode(path);
} else {
node = jcrFileSupportService.newFile(path);
}
return new JcrFileChannel(node);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new IOException(e);
}
}
// TODO
@Override
public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
logger.info("newByteChannel");
try {
final Node node = PathUtil.toNode(path);
return new JcrFileChannel(node);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new IOException(e);
}
}
@Override
public DirectoryStream<Path> newDirectoryStream(final Path dir, final DirectoryStream.Filter<? super Path> filter) throws IOException {
logger.info("new directory stream for {}", dir.toString());
if (dir instanceof JcrPath) {
return new JcrDirectoryStream((JcrPath) dir, filter);
} else {
throw new IllegalArgumentException("directory is not a JCR path");
}
}
// TODO
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
logger.info("createDirectory");
}
// TODO
@Override
public void delete(Path path) throws IOException {
logger.info("delete: {}", path);
final File file = path.toFile();
if (!file.exists()) {
throw new NoSuchFileException(path.toString());
} else {
// TODO delete
}
}
// TODO
@Override
public void copy(Path source, Path target, CopyOption... options) throws IOException {
logger.info("copy");
}
// TODO
@Override
public void move(Path source, Path target, CopyOption... options) throws IOException {
logger.info("move");
}
// TODO
@Override
public boolean isSameFile(Path path, Path path2) throws IOException {
logger.info("isSameFile");
return false;
}
// TODO
@Override
public boolean isHidden(Path path) throws IOException {
logger.info("isHidden");
return false;
}
@Override
public FileStore getFileStore(final Path path) throws IOException {
logger.info("getting file store for {}", path.toString());
return jcrFileStore;
}
// TODO
@Override
public void checkAccess(final Path path, final AccessMode... modes) throws IOException {
logger.info("checking access: {}", path.toString());
}
// TODO
@Override
public <V extends FileAttributeView> V getFileAttributeView(final Path path, final Class<V> type, final LinkOption... options) {
logger.info("getting file attribute view");
return null;
}
// TODO
@Override
public <A extends BasicFileAttributes> A readAttributes(final Path path, final Class<A> type, final LinkOption... options) throws IOException {
logger.info("reading attributes: {}, {}, {}", path, type, options);
if (type == BasicFileAttributes.class) {
final BasicFileAttributes basicFileAttributes = jcrFileSupportService.fromPath(path);
logger.info("basic file attributes: {}", basicFileAttributes);
return (A) basicFileAttributes;
} else {
throw new IOException("Unsupported file attributes type: " + type);
}
}
// TODO
@Override
public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) throws IOException {
logger.info("readAttributes: {}, {}, {}", path, attributes, options);
return Collections.emptyMap();
}
// TODO
@Override
public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException {
logger.info("setAttribute");
}
boolean isFile(final Node node) throws RepositoryException {
return jcrFileSupportService.isFile(node);
}
boolean isDirectory(final Node node) throws RepositoryException {
return jcrFileSupportService.isDirectory(node);
}
boolean isInCache(final Session session) {
return cache.containsKey(session);
}
void putIntoCache(final JcrFileSystem fileSystem) {
cache.put(fileSystem.getSession(), fileSystem);
}
void removeFromCache(final JcrFileSystem fileSystem) {
cache.remove(fileSystem.getSession());
}
}