| /* |
| * 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.spi.resource.provider; |
| |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.annotations.NotNull; |
| |
| import org.apache.sling.api.resource.LoginException; |
| import org.apache.sling.api.resource.PersistenceException; |
| import org.apache.sling.api.resource.Resource; |
| import org.apache.sling.api.resource.ResourceUtil; |
| import org.osgi.annotation.versioning.ConsumerType; |
| |
| /** |
| * API for providers of resources. Used by the {@link org.apache.sling.api.resource.ResourceResolver} to |
| * transparently access resources from different locations such as a JCR |
| * repository, a database, or bundle resources. |
| * <p> |
| * This extension point is defined by an abstract class (in contrast to |
| * an interface) as this allows to add new functionality in new versions |
| * without breaking any implementation. |
| * <p> |
| * This service is intended to be implemented by providers of resource |
| * instances on behalf of the {@link org.apache.sling.api.resource.ResourceResolver}. It |
| * is not intended to be used by client applications directly. A resource |
| * provider implements this service by extending this class. |
| * <p> |
| * A resource provider must set the {@link #PROPERTY_ROOT} property with an |
| * absolute path. This is the mount point of the resource provider. If there |
| * is more than one provider registering for the same root, only the one |
| * with the highest service ranking is used. |
| * <p> |
| * If a provider is used in the resource tree, it gets activated through |
| * a call of the {@link #start(ProviderContext)} method. If the |
| * provider is not used anymore within the resource tree, the |
| * {@link #stop()} method is called. Whenever |
| * information concerning the provider is changed while the provider |
| * is used, the {@link #update(long)} method is called. The provider context |
| * instance which is passed to the {@link #start(ProviderContext)} method |
| * contains the updated state. |
| * <p> |
| * Some resource providers might require (user) authentication. For example |
| * the JCR resource provider uses authenticated sessions. If a provider |
| * requires authentication it must indicate this by setting the service |
| * registration property {@link #PROPERTY_AUTHENTICATE} to either |
| * {@link #AUTHENTICATE_LAZY} or {@link #AUTHENTICATE_REQUIRED}. In these |
| * cases, the resource resolver calls {@link #authenticate(Map)} and on |
| * successful authentication the provider returns a state object for |
| * the current user. This object is passed into the provider with |
| * every method through {@link ResolveContext#getProviderState()}. |
| * If a provider requires authentication, the {@link #logout(Object)} method |
| * is called, when the resource resolver is closed. If the provider |
| * does not set this service property or sets it to {@link #AUTHENTICATE_NO} |
| * the {@link #authenticate(Map)} and {@link #logout(Object)} method |
| * are never called and therefore {@link ResolveContext#getProviderState()} |
| * will return {@code null}. |
| * <p> |
| * Each method gets the {@link ResourceContext} which gives access to |
| * further functionality. |
| * |
| * @since 1.0.0 (Sling API Bundle 2.11.0) |
| */ |
| @ConsumerType |
| public abstract class ResourceProvider<T> { |
| |
| /** |
| * The name of the service registration property containing the root path |
| * of the resources provided by this provider. |
| * If this property is missing, empty or invalid, the provider is ignored. |
| * (value is "provider.root") |
| */ |
| public static final String PROPERTY_ROOT = "provider.root"; |
| |
| /** |
| * Optional service registration property setting a name for the provider. |
| * The name must not be unique. The name in combination with the root |
| * can be used to identify a resource provider. |
| */ |
| public static final String PROPERTY_NAME = "provider.name"; |
| |
| /** |
| * The name of the service registration property containing a boolean |
| * flag indicating if the ResourceAccessSecurity service should be used for |
| * this provider or not. ResourceAccessSecurity should only be used if the |
| * underlying storage does not provide access control |
| * The default for this value is {@code false}. |
| * (value is "provider.useResourceAccessSecurity") |
| */ |
| public static final String PROPERTY_USE_RESOURCE_ACCESS_SECURITY = "provider.useResourceAccessSecurity"; |
| |
| /** |
| * Default value for {@link #PROPERTY_AUTHENTICATE} |
| * @see #PROPERTY_AUTHENTICATE |
| */ |
| public static final String AUTHENTICATE_NO = "no"; |
| |
| /** |
| * Value for {@link #PROPERTY_AUTHENTICATE} indicating authentication is required. |
| * @see #PROPERTY_AUTHENTICATE |
| */ |
| public static final String AUTHENTICATE_REQUIRED = "required"; |
| |
| /** |
| * Value for {@link #PROPERTY_AUTHENTICATE} indicating authentication is needed |
| * and will be done on demand. |
| * @see #PROPERTY_AUTHENTICATE |
| */ |
| public static final String AUTHENTICATE_LAZY = "lazy"; |
| |
| /** |
| * If a resource provider needs the user to be authenticated this property must be set |
| * to either {@link #AUTHENTICATE_LAZY} or {@link #AUTHENTICATE_REQUIRED}. |
| * If it is set to {@link #AUTHENTICATE_REQUIRED}, the {@link #authenticate(Map)} method |
| * is called when the resource resolver is created and only if authentication against |
| * all resource providers marked as required is successful, a resource resolver is |
| * created. Otherwise the creation fails. |
| * If a provider sets this property to {@link #AUTHENTICATE_LAZY}, the authenticate method |
| * is only invoked if a resource from this provider is requested. This might also happen |
| * for traversal or queries. If the authentication fails, resources from this provider |
| * are not accessible. |
| * If this property is not set or set to {@link #AUTHENTICATE_NO}, no authentication |
| * is required for this provider and the {@link #authenticate(Map)} is never invoked. |
| * String service property, default value is {@link #AUTHENTICATE_NO}. |
| * (value is "provider.authenticate") |
| */ |
| public static final String PROPERTY_AUTHENTICATE = "provider.authenticate"; |
| |
| /** |
| * A modifiable resource provider is capable of creating, changing and deleting resources. |
| * This means the methods {@link #create(ResolveContext, String, Map)}, |
| * {@link #delete(ResolveContext, Resource)} and adapting a resource to a modifiable |
| * value map is supported. |
| * If this flag is set to {@code false}, the resource resolver does not take this |
| * provider into account for modifications and modification operations to this provider |
| * always result in an exception. |
| * If this is set to {@code true}, the property {@link ResourceProvider#PROPERTY_AUTHENTICATE} |
| * must require authentication, otherwise this provider registration is considered |
| * invalid and the provider is not used. |
| * Boolean service property, default value is {@code false}. |
| * (value is "provider.modifiable") |
| */ |
| public static final String PROPERTY_MODIFIABLE = "provider.modifiable"; |
| |
| /** |
| * If this flag is set to {@code true}, the resource resolver will use this provider |
| * for the adaptTo() operation. |
| * Boolean service property, default value is {@code false}. |
| * (value is "provider.adaptable") |
| */ |
| public static final String PROPERTY_ADAPTABLE = "provider.adaptable"; |
| |
| /** |
| * If this flag is set to {@code true}, the resource resolver will call {@link #refresh(ResolveContext)} |
| * when it's refreshed itself. |
| * Boolean service property, default value is {@code false}. |
| * (value is "provider.refreshable") |
| */ |
| public static final String PROPERTY_REFRESHABLE = "provider.refreshable"; |
| |
| /** |
| * If this flag is set to {@code true}, the resource resolver will try to get the attribute |
| * names and the attribute values from this provider. |
| * Boolean service property, default value is {@code false}. |
| * (value is "provider.attributable") |
| */ |
| public static final String PROPERTY_ATTRIBUTABLE = "provider.attributable"; |
| |
| /** |
| * The authentication information property referring to the bundle |
| * providing a service for which a resource provider is to be retrieved. If |
| * this property is provided, the |
| * {@link org.apache.sling.api.resource.ResourceResolverFactory#SUBSERVICE} property may also be |
| * present. |
| * <p> |
| * {@link org.apache.sling.api.resource.ResourceResolverFactory} implementations must provide this |
| * property if their implementation of the |
| * {@link org.apache.sling.api.resource.ResourceResolverFactory#getServiceResourceResolver(Map)} method |
| * use a resource provider factory. |
| * <p> |
| * The type of this property, if present, is |
| * {@code org.osgi.framework.Bundle}. |
| */ |
| public static final String AUTH_SERVICE_BUNDLE = "sling.service.bundle"; |
| |
| /** |
| * The authentication information property indicating to use an |
| * administrative login. This property must be set if the resource |
| * resolver is created through {@link org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(Map)}. |
| */ |
| public static final String AUTH_ADMIN = "provider.auth.admin"; |
| |
| /** |
| * The authentication information property indicating that an existing resource resolver is being cloned. |
| * Providers that receive stateful objects as authentication information must deep-clone those objects |
| * when this property is present, to avoid inadvertent state sharing with the existing resolver. |
| * |
| * @since 1.2.0 |
| */ |
| public static final String AUTH_CLONE = "provider.auth.clone"; |
| |
| /** |
| * The resource type be set on resources returned by the |
| * {@link #listChildren(ResolveContext, Resource)} method to enable traversing the |
| * resource |
| * tree down to a deeply nested provided resource which has no concrete |
| * parent hierarchy (value is"sling:syntheticResourceProviderResource"). |
| * |
| * @see #listChildren(ResolveContext, Resource) |
| */ |
| public static final String RESOURCE_TYPE_SYNTHETIC = "sling:syntheticResourceProviderResource"; |
| |
| /** The context for this provider. */ |
| private volatile ProviderContext ctx; |
| |
| /** |
| * With a call to this method, the provider implementation is notified that |
| * it is used in the resource tree. |
| * @param ctx The context for this provider. |
| */ |
| public void start(@NotNull ProviderContext ctx) { |
| this.ctx = ctx; |
| } |
| |
| /** |
| * With a call to this method, the provider implementation is notified |
| * that it is not used anymore in the resource tree. |
| */ |
| public void stop() { |
| this.ctx = null; |
| } |
| |
| /** |
| * With a call to this method, the provider implementation is notified |
| * that any information regarding the registration of the provider |
| * has changed. For example, observation listeners might have changed. |
| * This method is only called while the provider is used in the resource |
| * tree. |
| * @param changeSet A bit set of provider info that has changed. |
| * @see ProviderContext#OBSERVATION_LISTENER_CHANGED |
| * @see ProviderContext#EXCLUDED_PATHS_CHANGED |
| */ |
| public void update(final long changeSet) { |
| // nothing to do here |
| } |
| |
| /** |
| * Get the current provider context. |
| * @return The provider context or {@code null} if the provider is currently |
| * not used in the resource tree. |
| */ |
| protected @Nullable ProviderContext getProviderContext() { |
| return this.ctx; |
| } |
| |
| /** |
| * Authenticate against the resource provider. |
| * <p> |
| * Returns a provider context object if authentication is successful. The |
| * context object is passed to the resource provider in all messages through |
| * the {@link ResourceContext}. A valid implementation might return {@code null} |
| * as the context information. |
| * <p> |
| * If authentication fails a {@code LoginException} must be thrown. |
| * <p> |
| * The returned context object grants access to the provided resources with |
| * privileges assigned to the service provided by the calling bundle. |
| * <p> |
| * The {@code authenticationInfo} map will in general contain the same |
| * information as provided to the respective {@link org.apache.sling.api.resource.ResourceResolver} |
| * method. For |
| * <p> |
| * The provided {@code authenticationInfo} map may be used to provide |
| * additional information such as the {@link #AUTH_SERVICE_BUNDLE}. |
| * If this property is provided, additional information like |
| * {@link org.apache.sling.api.resource.ResourceResolverFactory#SUBSERVICE} might be provided, but the |
| * {@link org.apache.sling.api.resource.ResourceResolverFactory#USER} and |
| * {@link org.apache.sling.api.resource.ResourceResolverFactory#PASSWORD} |
| * properties provided in the map must be ignored. |
| * <p> |
| * The {@link org.apache.sling.api.resource.ResourceResolverFactory#USER_IMPERSONATION} |
| * property is obeyed but requires that the |
| * authenticated user has permission to impersonate as the requested user. |
| * If such permission is missing, a {@code LoginException} is thrown. |
| * <p> |
| * The resource resolver implementation will call the {@link #logout(Object)} |
| * method once the resource resolver is closed. However, if the resource |
| * provider is already unregistered when the resource resolver is closed, |
| * logout can't be called. Therefore the returned state object might |
| * implement {@link java.io.Closeable}. In this case close is called |
| * on the state object. |
| * |
| * @param authenticationInfo A map of further credential information which |
| * may be used by the implementation to parameterize how the |
| * resource resolver is created. |
| * @return A context data object according to the |
| * {@code authenticationInfo}. |
| * @throws LoginException If an error occurs authenticating with the |
| * provided credential data. |
| * |
| * @see <a |
| * href="http://sling.apache.org/documentation/the-sling-engine/service-authentication.html">Service |
| * Authentication</a> |
| */ |
| public @Nullable T authenticate(final @NotNull Map<String, Object> authenticationInfo) |
| throws LoginException { |
| return null; |
| } |
| |
| /** |
| * If the provider requires authentication, this method is called with the state of the user |
| * returned by {@link #authenticate(Map)} once the resource resolver is closed. |
| * |
| * @param state The provider state returned by {@link #authenticate(Map)}. |
| */ |
| public void logout(final @Nullable T state) { |
| // do nothing |
| } |
| |
| /** |
| * The provider is updated to reflect the latest state. |
| * Resources which have changes pending are not discarded. |
| * {@link #revert(ResolveContext)} can be called to discard changes. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_REFRESHABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| */ |
| public void refresh(final @NotNull ResolveContext<T> ctx) { |
| // nothing to do here |
| } |
| |
| /** |
| * Returns {@code true} if this resource provider has not been closed |
| * yet and can still be used. |
| * <p> |
| * This method will never throw an exception |
| * even after the resource provider has been closed |
| * <p> |
| * This method is only called for resource providers which have a state and |
| * require authentication. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @return {@code true} if the resource provider has not been closed |
| * yet and is still active.. Once the resource provider has been closed |
| * or is not active anymore, this method returns {@code false}. |
| */ |
| public boolean isLive(final @NotNull ResolveContext<T> ctx) { |
| return true; |
| } |
| |
| /** |
| * Returns the parent resource from this resource provider or {@code null} if |
| * the resource provider cannot find it. |
| * |
| * The resource provider must not return cached instances for a resource as |
| * the resource resolver will update the resource meta data of the resource |
| * at the end of the resolution process and this meta data might be different |
| * depending on the full path of resource resolution passed into the |
| * resource resolver. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param child The child resource. |
| * @return {@code null} if this provider does not have a resource for |
| * the parent. |
| * @throws org.apache.sling.api.SlingException |
| * may be thrown in case of any problem creating the {@code Resource} instance. |
| */ |
| public @Nullable Resource getParent(final @NotNull ResolveContext<T> ctx, final @NotNull Resource child) { |
| final String parentPath = ResourceUtil.getParent(child.getPath()); |
| if (parentPath == null) { |
| return null; |
| } |
| return this.getResource(ctx, parentPath, ResourceContext.EMPTY_CONTEXT, null); |
| } |
| |
| /** |
| * Returns a resource from this resource provider or {@code null} if |
| * the resource provider cannot find it. The path must have the {@link #PROPERTY_ROOT} |
| * strings as its prefix. |
| * |
| * The resource provider must not return cached instances for a resource as |
| * the resource resolver will update the resource meta data of the resource |
| * at the end of the resolution process and this meta data might be different |
| * depending on the full path of resource resolution passed into the |
| * resource resolver. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param path The full path of the resource. |
| * @param resourceContext Additional information for resolving the resource |
| * @param parent Optional parent resource |
| * @return {@code null} If this provider does not have a resource for |
| * the path. |
| * @throws org.apache.sling.api.SlingException |
| * may be thrown in case of any problem creating the {@code Resource} instance. |
| */ |
| public abstract @Nullable Resource getResource(@NotNull final ResolveContext<T> ctx, |
| @NotNull final String path, |
| @NotNull final ResourceContext resourceContext, |
| @Nullable final Resource parent); |
| |
| /** |
| * Returns an {@code Iterator} of {@link Resource} objects loaded from |
| * the children of the given {@code Resource}. The returned {@link Resource} instances |
| * are attached to the same |
| * {@link org.apache.sling.api.resource.ResourceResolver} as the given {@code parent} resource. |
| * <p> |
| * This method may be called for resource providers whose root path list contains a path such |
| * that the resource path is a |
| * prefix of the list entry. This allows for the enumeration of deeply nested provided resources |
| * for which no actual parent |
| * hierarchy exists. |
| * <p> |
| * The returned iterator may in turn contain resources which do not actually exist but are required |
| * to traverse the resource |
| * tree. Such resources SHOULD be {@link org.apache.sling.api.resource.SyntheticResource} objects whose resource type MUST be set to |
| * {@link #RESOURCE_TYPE_SYNTHETIC}. |
| * |
| * As with {@link #getResource(ResolveContext, String, ResourceContext, Resource)} the returned Resource objects must |
| * not be cached objects. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param parent |
| * The {@link Resource Resource} whose children are requested. |
| * @return An {@code Iterator} of {@link Resource} objects or {@code null} if the resource |
| * provider has no children for the given resource. |
| * @throws NullPointerException |
| * If {@code parent} is {@code null}. |
| * @throws org.apache.sling.api.SlingException |
| * If any error occurs acquiring the child resource iterator. |
| */ |
| public abstract @Nullable Iterator<Resource> listChildren(final @NotNull ResolveContext<T> ctx, final @NotNull Resource parent); |
| |
| /** |
| * Returns a collection of attribute names whose value can be retrieved |
| * calling the {@link #getAttribute(ResolveContext, String)} method. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_ATTRIBUTABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @return A collection of attribute names or {@code null} |
| * @throws IllegalStateException if this resource provider has already been |
| * closed. |
| */ |
| public @Nullable Collection<String> getAttributeNames(final @NotNull ResolveContext<T> ctx) { |
| return null; |
| } |
| |
| /** |
| * Returns the value of the given resource provider attribute or {@code null} |
| * if the attribute is not set or not visible (as e.g. security |
| * sensitive attributes). |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_ATTRIBUTABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param name The name of the attribute to access |
| * @return The value of the attribute or {@code null} if the attribute |
| * is not set or not accessible. |
| * @throws IllegalStateException |
| * if this resource provider has already been closed. |
| */ |
| public @Nullable Object getAttribute(final @NotNull ResolveContext<T> ctx, final @NotNull String name) { |
| return null; |
| } |
| |
| /** |
| * Create a new resource at the given path. |
| * The new resource is put into the transient space of this provider |
| * until {@link #commit(ResolveContext)} is called. |
| * <p> |
| * A resource provider must value {@link org.apache.sling.api.resource.ResourceResolver#PROPERTY_RESOURCE_TYPE} |
| * to set the resource type of a resource. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param path The resource path. |
| * @param properties Optional properties |
| * @return The new resource. |
| * |
| * @throws PersistenceException If anything fails |
| */ |
| public @NotNull Resource create(final @NotNull ResolveContext<T> ctx, final String path, final Map<String, Object> properties) |
| throws PersistenceException { |
| throw new PersistenceException("create is not supported."); |
| } |
| |
| /** |
| * Delete the resource at the given path. |
| * This change is kept in the transient space of this provider |
| * until {@link #commit(ResolveContext)} is called. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param resource The resource to delete. |
| * |
| * @throws PersistenceException If anything fails |
| */ |
| public void delete(final @NotNull ResolveContext<T> ctx, final @NotNull Resource resource) |
| throws PersistenceException { |
| throw new PersistenceException("delete is not supported."); |
| } |
| |
| /** |
| * Revert all transient changes: create, delete and updates. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| */ |
| public void revert(final @NotNull ResolveContext<T> ctx) { |
| // nothing to do here |
| } |
| |
| /** |
| * Commit all transient changes: create, delete and updates |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @throws PersistenceException If anything fails |
| */ |
| public void commit(final @NotNull ResolveContext<T> ctx) |
| throws PersistenceException { |
| // nothing to do here |
| } |
| |
| /** |
| * Are there any transient changes? |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @return {@code true} if there are pending changes. |
| */ |
| public boolean hasChanges(final @NotNull ResolveContext<T> ctx) { |
| return false; |
| } |
| |
| /** |
| * Get the optional query language provider. |
| * If the provider supports this kind of query, it must return a query provider implementation |
| * if the provider is active. It should not return a query provider if it is not |
| * active. |
| * This method is called for each query, therefore the provider implementation |
| * might cache the provider object. |
| * |
| * @return A query language provider if this resource provider supports this type of querying. |
| */ |
| public @Nullable QueryLanguageProvider<T> getQueryLanguageProvider() { |
| return null; |
| } |
| |
| /** |
| * Adapts the provider to another type. |
| * <p> |
| * Please not that it is explicitly left as an implementation detail whether |
| * each call to this method with the same {@code type} yields the same |
| * object or a new object on each call. |
| * <p> |
| * Implementations of this method should document their adapted types as |
| * well as their behavior with respect to returning newly created or not |
| * instance on each call. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_ADAPTABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param <AdapterType> The generic type to which this resource is adapted to. |
| * @param type The generic type to which this resource is adapted to. |
| * @return The adapter target or {@code null} if the provider cannot |
| * be adapt to the requested type. |
| */ |
| public @Nullable <AdapterType> AdapterType adaptTo(final @NotNull ResolveContext<T> ctx, |
| final @NotNull Class<AdapterType> type) { |
| return null; |
| } |
| |
| /** |
| * This method copies the subgraph rooted at, and including, the resource at |
| * {@code srcAbsPath} to the new location at {@code destAbsPath} and |
| * adds it as a child node of the resource at {@code destAbsPath}. |
| * <p> |
| * Both resources are resources from this provider and the full tree is |
| * provided by this provider as well. |
| * <p> |
| * The resource at {@code destAbsPath} needs to exist, if not a {@code PersistenceException} |
| * is thrown. If a child resource with the same name already exists at {@code destAbsPath} |
| * a {@code PersistenceException} is thrown. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param srcAbsPath the path of the resource to be copied. |
| * @param destAbsPath the location to which the resource at |
| * {@code srcAbsPath} is to be copied. |
| * @throws PersistenceException If an error occurs. |
| * @return {@code true} if the provider can perform the copy |
| */ |
| public boolean copy(final @NotNull ResolveContext<T> ctx, |
| final @NotNull String srcAbsPath, |
| final @NotNull String destAbsPath) throws PersistenceException { |
| return false; |
| } |
| |
| /** |
| * This method moves the subgraph rooted at, and including, the resource at |
| * {@code srcAbsPath} to the new location at {@code destAbsPath} and |
| * adds it as a child node of the resource at {@code destAbsPath}. |
| * <p> |
| * Both resources are resources from this provider and the full tree is |
| * provided by this provider as well. |
| * <p> |
| * The resource at {@code destAbsPath} needs to exist, if not a {@code PersistenceException} |
| * is thrown. If a child resource with the same name already exists at {@code destAbsPath} |
| * a {@code PersistenceException} is thrown. |
| * <p> |
| * This method is only called if the provider supports this and indicates |
| * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}. |
| * |
| * @param ctx The {@link ResolveContext}. |
| * @param srcAbsPath the path of the resource to be copied. |
| * @param destAbsPath the location to which the resource at |
| * {@code srcAbsPath} is to be moved. |
| * @throws PersistenceException If an error occurs. |
| * @return {@code true} if the provider can perform the move |
| */ |
| public boolean move(final @NotNull ResolveContext<T> ctx, |
| final @NotNull String srcAbsPath, |
| final @NotNull String destAbsPath) throws PersistenceException { |
| return false; |
| } |
| } |