Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 27949 invoked from network); 1 Feb 2005 15:58:59 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 1 Feb 2005 15:58:59 -0000 Received: (qmail 51621 invoked by uid 500); 1 Feb 2005 15:58:33 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 51349 invoked by uid 500); 1 Feb 2005 15:58:31 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 51256 invoked by uid 99); 1 Feb 2005 15:58:30 -0000 X-ASF-Spam-Status: No, hits=0.1 required=10.0 tests=FORGED_RCVD_HELO X-Spam-Check-By: apache.org Received-SPF: neutral (hermes.apache.org: local policy) Received: from out1.smtp.messagingengine.com (HELO out1.smtp.messagingengine.com) (66.111.4.25) by apache.org (qpsmtpd/0.28) with ESMTP; Tue, 01 Feb 2005 07:58:29 -0800 Received: from frontend3.messagingengine.com (frontend3.internal [10.202.2.152]) by frontend1.messagingengine.com (Postfix) with ESMTP id EC999C53093 for ; Tue, 1 Feb 2005 10:58:22 -0500 (EST) X-Sasl-enc: p2NOPN4JnLcdI6paIhvqJQ 1107273502 Received: from [172.16.53.49] (65-65-189-5.ded.swbell.net [65.65.189.5]) by frontend3.messagingengine.com (Postfix) with ESMTP id 8DB97287B7 for ; Tue, 1 Feb 2005 10:58:20 -0500 (EST) Message-ID: <41FFA7CA.3040005@alumni.rice.edu> Date: Tue, 01 Feb 2005 10:01:14 -0600 From: "B. K. Oxley (binkley)" Organization: The Oxley Family User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Jakarta Commons Developers List Subject: Re: [vfs] proposal: FileUtils References: <41F17027.30402@alumni.rice.edu> <41F17CF5.4060803@ops.co.at> <41F18708.1070709@alumni.rice.edu> <41FD61C6.9000706@alumni.rice.edu> <41FDDE5F.1070203@ops.co.at> <41FEC1A9.60607@alumni.rice.edu> In-Reply-To: <41FEC1A9.60607@alumni.rice.edu> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Continuing the command pattern, I rejiggered the Save command to use a Backup command rather than hard-coding the backup policy: public class Save implements IOOperation { private final Backup backup; private final InputStream newContents; private final FuFile original; public Save(final Backup backup, final InputStream newContents, final FuFile original) { if (null == backup) throw new NullPointerException(); if (null == newContents) throw new NullPointerException(); if (null == original) throw new NullPointerException(); this.backup = backup; this.newContents = newContents; this.original = original; } public void execute() throws IOException { backup.prepare(original, new Write(newContents, original)).execute(); } } Notice the "prepare" method which is an example of delayed initialization. Since Backup needs a next operation, but Save both needs a Backup and creates the next operation (a Write command), I cannot both create an immutable Backup and create an immutable Save at the same time. And looking at Backup: public abstract class Backup implements IOOperation { protected final FuPolicy policy; private FuFile original; private IOOperation next; protected Backup(final FuPolicy policy) { if (null == policy) throw new NullPointerException(); this.policy = policy; } protected FuFile getOriginal() { return original; } protected IOOperation getNext() { return next; } public Backup prepare(final FuFile original, final IOOperation next) { if (null == original) throw new NullPointerException(); if (null == next) throw new NullPointerException(); this.original = original; this.next = next; return this; } } And two implementations: public class NoBackup extends Backup { public NoBackup(final FuPolicy policy) { super(policy); } public void execute() throws IOException { final FuFile original = getOriginal(); new Delete(original, policy.createScratch(original), getNext()).execute(); } } public class SimpleBackup extends Backup { public SimpleBackup(final FuPolicy policy) { super(policy); } public void execute() throws IOException { final FuFile original = getOriginal(); final FuFile backup = policy.createBackup(original); new Delete(backup, policy.createScratch(backup), new Move(original, backup, getNext())).execute(); } } The second implementation, "SimpleBackup", implements the policy hard-coded previously in Save. I still use the FuPolicy object to decide how to make a temporary and a backup file. I think that creating a backup should be merged into the Backup object instead, but I haven't decided what the best way to do that is. The problem scenario is an Emacs-scheme multiple backup (e.g., foo.txt, foo.txt.~1~, foo.txt.~2~, etc.). There the policy for naming backups and the backup command are very intimate, and really belong in the same object. Cheers, --binkley --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org