| 
What this is
 Other links
 The source code
/*****************************************************************************
 * Sun Public License Notice
 *
 *
 * The contents of this file are subject to the Sun Public License Version
 * 1.0 (the "License"). You may not use this file except in compliance with
 * the License. A copy of the License is available at http://www.sun.com/
 *
 * The Original Code is the CVS Client Library.
 * The Initial Developer of the Original Code is Robert Greig.
 * Portions created by Robert Greig are Copyright (C) 2000.
 * All Rights Reserved.
 *
 * Contributor(s): Robert Greig.
 *****************************************************************************/
package org.netbeans.lib.cvsclient.command;
import java.io.*;
import java.util.*;
import org.netbeans.lib.cvsclient.*;
import org.netbeans.lib.cvsclient.admin.*;
import org.netbeans.lib.cvsclient.connection.*;
import org.netbeans.lib.cvsclient.event.*;
import org.netbeans.lib.cvsclient.request.*;
/**
 * A class that provides common functionality for many of the CVS command
 * that send similar sequences of requests.
 * @author  Robert Greig
 */
public abstract class BasicCommand extends BuildableCommand {
    /**
     * The requests that are sent and processed.
     */
    protected List requests = new LinkedList();
    /**
     * The client services that are provided to this command.
     */
    protected ClientServices clientServices;
    /**
     * Whether to update recursively.
     */
    private boolean recursive = true;
    /**
     * The files and/or directories to operate on.
     */
    protected File[] files;
    /**
     * Gets the value of the recursive option.
     * @return true if recursive, false if not
     * @deprecated use isRecursive instead
     */
    public boolean getRecursive() {
        return recursive;
    }
    /**
     * Gets the value of the recursive option.
     * @return true if recursive, false if not
     */
    public boolean isRecursive() {
        return recursive;
    }
    /**
     * Sets the value of the recursive option.
     * @param r true if the command should recurse, false otherwise
     */
    public void setRecursive(boolean recursive) {
        this.recursive = recursive;
    }
    /**
     * Set the files and/or directories on which to execute the command.
     * The way these are processed is:
 sendEntryAndModifiedRequests.
     */
    protected boolean doesCheckFileTime() {
        return true;
    }
    /**
     * Send an Entry followed by a Modified or Unchanged request based on
     * whether the file has been untouched on the local machine.
     *
     * @param entry         the entry for the file
     * @param file          the file in question
     */
    protected void sendEntryAndModifiedRequests(Entry entry,
                                                File file) {
        if (entry == null) {
            return;
        }
        // for deleted added files, don't send anything..
        if (file != null && !file.exists() && entry.isNewUserFile()) {
            return;
        }
        Date entryLastModified = entry.getLastModified();
        boolean hadConflicts = entry.hadConflicts();
        if (!hadConflicts) {
            // we null out the conflict field if there is no conflict
            // because we use that field to store the timestamp of the
            // file (just like command-line CVS). There is no point
            // in sending this information to the CVS server, even
            // though it should be ignored by the server.
            entry.setConflict(null);
        }
        addRequest(new EntryRequest(entry));
        if (file == null || !file.exists() || entry.isUserFileToBeRemoved()) {
            return;
        }
        if (doesCheckFileTime() && !hadConflicts && entryLastModified != null) {
            if (DateComparator.getInstance().equals(file.lastModified(),
                                                    entryLastModified.getTime())) {
                addRequest(new UnchangedRequest(file.getName()));
                return;
            }
        }
        addRequest(new ModifiedRequest(file, entry.isBinary()));
    }
    /**
     * Adds the appropriate requests for a given directory. Sends a
     * directory request followed by as many Entry and Modified requests
     * as required
     * @param directory the directory to send requests for
     * @throws IOException if an error occurs constructing the requests
     */
    protected void addRequestsForDirectory(File directory)
            throws IOException {
        if (!directory.exists()) {
            return;
        }
        addDirectoryRequest(directory);
        List localFiles = createLocalFileList(directory);
        List subDirectories = null;
        if (isRecursive()) {
            subDirectories = new LinkedList();
        }
        // get all the entries we know about, and process them
        for (Iterator it = clientServices.getEntries(directory); it.hasNext();) {
            final Entry entry = (Entry)it.next();
            if (entry.isDirectory()) {
                if (isRecursive()) {
                    subDirectories.add(new File(directory, entry.getName()));
                }
            }
            else {
                final File file = new File(directory, entry.getName());
                addRequestForFile(file, entry);
                localFiles.remove(file);
            }
        }
        
        // In case that CVS folder does not exist, we need to process all
        // directories that have CVS subfolders:
        if (isRecursive() && !new File(directory, "CVS").exists()) {
            File[] subFiles = directory.listFiles();
            if (subFiles != null) {
                for (int i = 0; i < subFiles.length; i++) {
                    if (subFiles[i].isDirectory() && new File(subFiles[i], "CVS").exists()) {
                        subDirectories.add(subFiles[i]);
                    }
                }
            }
        }
        for (Iterator it = localFiles.iterator(); it.hasNext();) {
            String localFileName = ((File)it.next()).getName();
            if (!clientServices.shouldBeIgnored(directory, localFileName)) {
                addRequest(new QuestionableRequest(localFileName));
            }
        }
        if (isRecursive()) {
            for (Iterator it = subDirectories.iterator(); it.hasNext();) {
                File subdirectory = (File)it.next();
                File cvsSubDir = new File(subdirectory, "CVS"); //NOI18N
                if (cvsSubDir.exists()) {
                    addRequestsForDirectory(subdirectory);
                }
            }
        }
    }
    private List createLocalFileList(File directory) {
        List localFiles = new LinkedList();
        File[] files = directory.listFiles();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                if (!files[i].isDirectory()) {
                    localFiles.add(files[i]);
                }
            }
        }
        return localFiles;
    }
    /**
     * This method is called for each explicit file and for files within a
     * directory.
     */
    protected void addRequestForFile(File file, Entry entry) {
        sendEntryAndModifiedRequests(entry, file);
    }
    /**
     * Add the appropriate requests for a single file. A directory request
     * is sent, followed by an Entry and Modified request
     * @param file the file to send requests for
     * @throws IOException if an error occurs constructing the requests
     */
    protected void addRequestsForFile(File file) throws IOException {
        addDirectoryRequest(file.getParentFile());
        try {
            final Entry entry = clientServices.getEntry(file);
            // a non-null entry means the file does exist in the
            // Entries file for this directory
            if (entry != null) {
                addRequestForFile(file, entry);
            }
        }
        catch (IOException ex) {
            System.err.println("An error occurred getting the Entry " +
                               "for file " + file + ": " + ex);
            ex.printStackTrace();
        }
    }
    /**
     * Adds a DirectoryRequest (and maybe a StickyRequest) to the request list.
     */
    protected final void addDirectoryRequest(File directory) {
        // remove localPath prefix from directory. If left with
        // nothing, use dot (".") in the directory request
        String dir = getRelativeToLocalPathInUnixStyle(directory);
        try {
            String repository = clientServices.getRepositoryForDirectory(
                    directory.getAbsolutePath());
            addRequest(new DirectoryRequest(dir, repository));
            String tag = clientServices.getStickyTagForDirectory(directory);
            if (tag != null) {
                addRequest(new StickyRequest(tag));
            }
        }
        catch (FileNotFoundException ex) {
            // we can ignore this exception safely because it just means
            // that the user has deleted a directory referenced in a
            // CVS/Entries file
        }
        catch (IOException ex) {
            System.err.println("An error occurred reading the respository " +
                               "for the directory " + dir + ": " + ex);
            ex.printStackTrace();
        }
    }
    /**
     * Add the argument requests. The argument requests are created using
     * the original set of files/directories passed in. Subclasses of this
     * class should call this method at the appropriate point in their
     * execute() method. Note that arguments are appended to the list.
     */
    protected void addArgumentRequests() {
        if (files == null) {
            return;
        }
        for (int i = 0; i < files.length; i++) {
            final File file = files[i];
            String relativePath = getRelativeToLocalPathInUnixStyle(file);
            addRequest(new ArgumentRequest(relativePath));
        }
    }
    /**
     * Execute a command. This implementation sends a Root request, followed
     * by as many Directory and Entry requests as is required by the recurse
     * setting and the file arguments that have been set. Subclasses should
     * call this first, and tag on the end of the requests list any further
     * requests and, finally, the actually request that does the command (e.g.
     * update, statusetc.) * @param client the client services object that provides any necessary * services to this command, including the ability to actually process * all the requests * @throws CommandException if an error occurs executing the command */ public void execute(ClientServices client, EventManager em) throws CommandException, AuthenticationException { requests.clear(); super.execute(client, em); clientServices = client; if (client.isFirstCommand()) { addRequest(new RootRequest(client.getRepository())); } addFileRequests(); } private void addFileRequests() throws CommandException { try { if (files != null && files.length > 0) { for (int i = 0; i < files.length; i++) { addRequests(files[i]); } } else { // if no arguments have been specified, then specify the // local directory - the "top level" for this command if (assumeLocalPathWhenUnspecified()) { addRequests(new File(getLocalDirectory())); } } } catch (Exception ex) { throw new CommandException(ex, ex.getLocalizedMessage()); } } /** * The result from this command is used only when the getFiles() returns null or empty array. * in such a case and when this method returns true, it is assumed the localpath should be taken * as the 'default' file for the building of requests. * Generally assumed to be true. Can be overriden by subclasses. However make sure you know what you are doing. :) */ protected boolean assumeLocalPathWhenUnspecified() { return true; } /** * Adds the specified request to the request list. */ protected final void addRequest(Request request) { requests.add(request); } /** * Adds the request for the current working directory. */ protected final void addRequestForWorkingDirectory(ClientServices clientServices) throws IOException { addRequest(new DirectoryRequest(".", //NOI18N clientServices.getRepositoryForDirectory(getLocalDirectory()))); } /** * If the specified value is true, add a ArgumentRequest for the specified * argument. */ protected final void addArgumentRequest(boolean value, String argument) { if (!value) { return; } addRequest(new ArgumentRequest(argument)); } /** * Appends the file's names to the specified buffer. */ protected final void appendFileArguments(StringBuffer buffer) { File[] files = getFiles(); if (files == null) { return; } for (int index = 0; index < files.length; index++) { if (index > 0) { buffer.append(' '); } buffer.append(files[index].getName()); } } }  | 
| ... this post is sponsored by my books ... | |
         
           #1 New Release!  | 
      
         
           FP Best Seller  | 
  
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse 
URI on this website is
paid back to open source projects.