You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by un...@apache.org on 2003/11/04 17:58:11 UTC

cvs commit: cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository SourceRepositoryImpl.java SourceRepository.java

unico       2003/11/04 08:58:11

  Modified:    src/blocks/repository/java/org/apache/cocoon/components/repository
                        SourceRepositoryImpl.java SourceRepository.java
  Log:
  follow spec closer on move/copy semantics, factor out some common code
  
  Revision  Changes    Path
  1.3       +120 -62   cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository/SourceRepositoryImpl.java
  
  Index: SourceRepositoryImpl.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository/SourceRepositoryImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SourceRepositoryImpl.java	3 Nov 2003 08:41:14 -0000	1.2
  +++ SourceRepositoryImpl.java	4 Nov 2003 16:58:11 -0000	1.3
  @@ -97,10 +97,10 @@
       
       // ---------------------------------------------------- repository operations
       
  -    public int save(String in, String out) throws IOException {
  +    public int save(String in, String out) throws IOException, SourceException {
           
           if (getLogger().isDebugEnabled()) {
  -            getLogger().debug("save: " + in + "/" + out);
  +            getLogger().debug("save: "+in+"/"+out);
           }
           
           Source source = null;
  @@ -163,7 +163,7 @@
           
       }
       
  -    public int makeCollection(String location) throws IOException {
  +    public int makeCollection(String location) throws IOException, SourceException {
           
           if (getLogger().isDebugEnabled()) {
               getLogger().debug("makeCollection: " + location);
  @@ -219,7 +219,7 @@
        * @return  a http status code describing the exit status.
        * @throws IOException
        */
  -    public int remove(String location) throws IOException {
  +    public int remove(String location) throws IOException, SourceException {
           
           Source source = null;
           try {
  @@ -281,73 +281,86 @@
           return STATUS_OK;
       }
       
  -    public int move(String from, String to) throws IOException {
  +    public int move(String from, String to, boolean recurse, boolean overwrite) 
  +    throws IOException, SourceException {
           
  -        if (getLogger().isDebugEnabled()) {
  -            getLogger().debug("move: " + from + " -> " + to);
  -        }
  -        
  -        if (from != null && from.equals(to)) {
  -            final String message = 
  -                "move() is not allowed: " +
  -                "The source and destination URIs are the same";
  -            getLogger().warn(message);
  -            return STATUS_NOT_ALLOWED;
  -        }
  -        Source source = null;
  -        Source destination = null;
  -        try {
  -            source = m_resolver.resolveURI(from);
  -            destination = m_resolver.resolveURI(to);
  -            return move(source, destination);
  -        }
  -        catch (IOException e) {
  -            getLogger().error("Unexpected exception during move().",e);
  -            throw e;
  -        }
  -        finally {
  -            if (source != null) {
  -                m_resolver.release(source);
  -            }
  -            if (destination != null) {
  -                m_resolver.release(destination);
  -            }
  +        int status = doCopy(from,to,recurse,overwrite);
  +        if (status == STATUS_CREATED || status == STATUS_NO_CONTENT) {
  +            // TODO: handle partially successful copies
  +            remove(from);
  +            // TODO: remove properties
           }
  +        return status;
       }
       
  -    private int move(Source source, Source destination) throws IOException {
  -        if (!source.exists()) {
  -            final String message =
  -                "Trying to move a non-existing source.";
  -            getLogger().warn(message);
  -            return STATUS_NOT_FOUND;
  -        }
  -        if (destination.exists()) {
  -            remove((ModifiableSource) destination);
  -        }
  -        SourceUtil.move(source, destination);
  -        return STATUS_CREATED;
  +    public int copy(String from, String to, boolean recurse, boolean overwrite) 
  +    throws IOException, SourceException {
  +        
  +        return doCopy(from,to,recurse,overwrite);
  +        
       }
       
  -    public int copy(String from, String to) throws IOException {
  +    private int doCopy(String from, String to, boolean recurse, boolean overwrite) 
  +    throws IOException {
           
           if (getLogger().isDebugEnabled()) {
  -            getLogger().debug("copy: " + from + " -> " + to);
  +            getLogger().debug("copy: " + from + " -> " + to 
  +                + " (recurse=" + recurse + ", overwrite=" + overwrite + ")");
           }
           
           if (from != null && from.equals(to)) {
               final String message = 
  -                "copy() is not allowed: " +
  -                "The source and destination URIs are the same";
  +                "copy() is forbidden: " +
  +                "The source and destination URIs are the same.";
               getLogger().warn(message);
  -            return STATUS_NOT_ALLOWED;
  +            return STATUS_FORBIDDEN;
           }
           Source source = null;
           Source destination = null;
           try {
               source = m_resolver.resolveURI(from);
               destination = m_resolver.resolveURI(to);
  -            return copy(source, destination);
  +            if (!source.exists()) {
  +                final String message =
  +                    "Trying to copy a non-existing source.";
  +                getLogger().warn(message);
  +                return STATUS_NOT_FOUND;
  +            }
  +            int status;
  +            if (destination.exists()) {
  +                if (!overwrite) {
  +                    final String message =
  +                        "Failed precondition in copy(): " +
  +                        "Destination resource already exists.";
  +                    getLogger().warn(message);
  +                    return STATUS_PRECONDITION_FAILED;
  +                }
  +                remove(destination);
  +                status = STATUS_NO_CONTENT;
  +            } 
  +            else {
  +                Source parent = null;
  +                try {
  +                    parent = getParent(destination);
  +                    if (!parent.exists()) {
  +                        final String message = 
  +                            "Conflict in copy(): " +
  +                            "A resource cannot be created at the destination " +
  +                            "until one or more intermediate collections have been " +
  +                            "created.";
  +                        getLogger().warn(message);
  +                        return STATUS_CONFLICT;
  +                    }
  +                }
  +                finally {
  +                    if (parent != null) {
  +                        m_resolver.release(parent);
  +                    }
  +                }
  +                status = STATUS_CREATED;
  +            }
  +            copy(source,destination,recurse);
  +            return status;
           }
           catch (IOException e) {
               getLogger().error("Unexpected exception during copy().",e);
  @@ -363,18 +376,63 @@
           }
       }
       
  -    private int copy(Source source, Source destination) throws IOException {
  -        if (!source.exists()) {
  -            final String message =
  -                "Trying to copy a non-existing source";
  -            getLogger().warn(message);
  -            return STATUS_NOT_FOUND;
  +    private int copy(Source source, Source destination, boolean recurse)
  +    throws IOException {
  +        
  +        if (getLogger().isDebugEnabled()) {
  +            getLogger().debug("copy: " + source.getURI() + " -> " + destination.getURI());
           }
  -        if (destination.exists()) {
  -            remove((ModifiableSource) destination);
  +        
  +        if (source instanceof TraversableSource) {
  +            final TraversableSource origin = (TraversableSource) source;
  +            ModifiableTraversableSource target = null;
  +            if (origin.isCollection()) {
  +                if (!(destination instanceof ModifiableTraversableSource)) {
  +                    final String message = "copy() is forbidden: " +
  +                        "Cannot create a collection at the indicated destination.";
  +                    getLogger().warn(message);
  +                    return STATUS_FORBIDDEN;
  +                }
  +                // TODO: copy properties
  +                target = ((ModifiableTraversableSource) destination);
  +                target.makeCollection();
  +                if (recurse) {
  +                    Iterator children = origin.getChildren().iterator();
  +                    while (children.hasNext()) {
  +                        TraversableSource child = (TraversableSource) children.next();
  +                        int status = copy(child,target.getChild(child.getName()),recurse);
  +                        // TODO: record this status
  +                        // according to the spec we must continue moving files even though
  +                        // a part of the move has not succeeded
  +                    }
  +                }
  +                return STATUS_CREATED;
  +            }
  +        }
  +        if (destination instanceof ModifiableSource) {
  +            // TODO: copy properties
  +            SourceUtil.copy(source, destination);
  +        }
  +        else {
  +            final String message = "copy() is forbidden: " +
  +                "Cannot create a resource at the indicated destination.";
  +            getLogger().warn(message);
  +            return STATUS_FORBIDDEN;
           }
  -        SourceUtil.copy(source, destination);
           return STATUS_CREATED;
  -    }    
  +    }
       
  +    private Source getParent(Source source) throws IOException {
  +        if (source instanceof TraversableSource) {
  +            return ((TraversableSource) source).getParent();
  +        }
  +        else {
  +            String uri = source.getURI();
  +            int index = uri.lastIndexOf('/');
  +            if (index != -1) {
  +                return m_resolver.resolveURI(uri.substring(index+1));
  +            }
  +        }
  +        return null;
  +    }
   }
  
  
  
  1.3       +41 -15    cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository/SourceRepository.java
  
  Index: SourceRepository.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository/SourceRepository.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SourceRepository.java	30 Oct 2003 21:57:47 -0000	1.2
  +++ SourceRepository.java	4 Nov 2003 16:58:11 -0000	1.3
  @@ -72,30 +72,45 @@
       public static final String ROLE = SourceRepository.class.getName();
       
       /**
  -     * Status OK (<code>200</code>).
  +     * Status OK (<b>200</b>).
        */
       public static final int STATUS_OK = 200;
       
       /**
  -     * Status CREATED (<code>201</code>).
  +     * Status CREATED (<b>201</b>).
        */
       public static final int STATUS_CREATED = 201;
  -
  +    
  +    /**
  +     * Status NO_CONTENT (<b>204</b>).
  +     */
  +    public static final int STATUS_NO_CONTENT = 204;
  +    
       /**
  -     * Status NOT_FOUND (<code>404</code>).
  +     * Status FORBIDDEN (<b>403</b>).
  +     */
  +    public static final int STATUS_FORBIDDEN = 403;
  +    
  +    /**
  +     * Status NOT_FOUND (<b>404</b>).
        */
       public static final int STATUS_NOT_FOUND = 404;
   
       /**
  -     * Status NOT_ALLOWED (<code>405</code>).
  +     * Status NOT_ALLOWED (<b>405</b>).
        */
       public static final int STATUS_NOT_ALLOWED = 405;
       
       /**
  -     * Status CONFLICT (<code>409</code>).
  +     * Status CONFLICT (<b>409</b>).
        */
       public static final int STATUS_CONFLICT = 409;
       
  +    /**
  +     * Status PRECONDITION_FAILED (<b>412</b>)
  +     */
  +    public static final int STATUS_PRECONDITION_FAILED = 412;
  +    
       
       /**
        * Saves a Source by either creating a new one or overwriting the previous one.
  @@ -104,8 +119,9 @@
        * @param out  the Source location to write to.
        * @return  a status code describing the exit status.
        * @throws IOException
  +     * @throws SourceException
        */
  -    public abstract int save(String in, String out) throws IOException;
  +    public abstract int save(String in, String out) throws IOException, SourceException;
       
       /**
        * Create a Source collection.
  @@ -113,8 +129,9 @@
        * @param location  the location of the source collection to create.
        * @return  a status code describing the exit status.
        * @throws IOException
  +     * @throws SourceException
        */
  -    public abstract int makeCollection(String location) throws IOException;
  +    public abstract int makeCollection(String location) throws IOException, SourceException;
       
       /**
        * Deletes a Source and all of its descendants.
  @@ -122,27 +139,36 @@
        * @param location  the location of the source to delete.
        * @return  a status code describing the exit status.
        * @throws IOException
  +     * @throws SourceException
        */
  -    public abstract int remove(String location) throws SourceException, IOException;
  +    public abstract int remove(String location) throws IOException, SourceException;
       
       /**
        * Move a Source from one location to the other.
        * 
  -     * @param from  the source location.
  -     * @param to    the destination location.
  +     * @param from       the source location.
  +     * @param to         the destination location.
  +     * @param recurse    whether to move all the source descendents also.
  +     * @param overwrite  whether to overwrite the destination source if it exists.
        * @return  a status code describing the exit status.
        * @throws IOException
  +     * @throws SourceException
        */
  -    public abstract int move(String from, String to) throws IOException;
  +    public abstract int move(String from, String to, boolean recurse, boolean overwrite) 
  +        throws IOException, SourceException;
       
       /**
        * Copy a Souce from one location to the other.
        * 
  -     * @param from  the source location.
  -     * @param to    the destination location.
  +     * @param from       the source location.
  +     * @param to         the destination location.
  +     * @param recurse    whether to move all the source descendents also.
  +     * @param overwrite  whether to overwrite the destination source if it exists.
        * @return  a status code describing the exit status.
        * @throws IOException
  +     * @throws SourceException
        */
  -    public abstract int copy(String from, String to) throws IOException;
  +    public abstract int copy(String from, String to, boolean recurse, boolean overwrite) 
  +        throws IOException, SourceException;
       
   }