alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

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 NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */



package org.netbeans.modules.javacvs.commands;


import org.openide.util.*;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
import java.io.*;
import java.util.*;
import java.awt.Dialog;

//import org.netbeans.modules.javacvs.*;
import org.netbeans.lib.cvsclient.command.update.*;
import org.netbeans.lib.cvsclient.command.add.*;
import org.netbeans.lib.cvsclient.command.status.*;
import org.netbeans.lib.cvsclient.command.checkout.*;
import org.netbeans.lib.cvsclient.command.remove.*;
import org.netbeans.lib.cvsclient.command.commit.*;
import org.netbeans.lib.cvsclient.command.*;
import org.netbeans.lib.cvsclient.admin.*;
import org.netbeans.modules.javacvs.JavaCvsFileSystem;
// vcscore cache import !!!
import org.netbeans.modules.vcscore.cache.*;
import org.netbeans.modules.javacvs.caching.*;
import org.netbeans.modules.javacvs.commands.JavaCvsStatusManager;


/**
 *
 * @author  mkleint
 * @version
 */
public abstract class CacheUpdatingFsCommand extends FileSystemCommand {
    
    public static final String UPD_CONFLICT = "C"; // NOI18N
    public static final String UPD_MODIFIED = "M"; // NOI18N
    public static final String UPD_ADDED = "A"; // NOI18N
    public static final String UPD_REMOVE = "R"; // NOI18N
    public static final String UPD_UPDATE = "U";     // NOI18N
    public static final String UPD_PATCH = "P";     // NOI18N
    public static final String UPD_UNKNOWN = "?";  // NOI18N
    public static final String UPD_TAG = "T"; // NOI18N
    public static final String UPD_DEL_TAG = "D"; // NOI18N
    public static final String UPD_MERGED = "G"; // NOI18N
    
    private static final String STATUS_NO_REVISION_CONTROL_FILE = "No revision control file";  // NOI18N
    
    private HashMap dirs;
    private HashSet newAddedDirs;
    private boolean refreshing;
    
    /** Holds value of property fullEntriesUpdate. */
    private boolean fullEntriesUpdate;
    
    public CacheUpdatingFsCommand() {
        super();
        dirs = new HashMap();
        newAddedDirs = new HashSet();
        refreshing = false;
    }
    
    public CacheUpdatingFsCommand(ClientProvider provider) {
        this();
        setClientProvider(provider);
    }
    
    public void setRefreshing(boolean refreshing) {
        this.refreshing = refreshing;
    }
    
    public boolean isRefreshing() {
        return refreshing;
    }
    
    protected void updateCache(DefaultFileInfoContainer updInfo) {
        if (updInfo == null || updInfo.getFile() == null) return;       
        HashMap dir = getDirMap(updInfo.getFile().getParentFile());
        String type = updInfo.getType();
        String status = ""; // NOI18N
        if (type.equals(UPD_TAG) || type.equals(UPD_DEL_TAG)) {
            return;
        }
        if (type.equals(UPD_UPDATE) || type.equals(UPD_PATCH)) {
            // we are up-to-date
            status = JavaCvsStatusManager.UPTODATE;
        }
        // TODO- HACK ?? - MAYBE ADDED SHOULD BECOME Up-to-date.. are just A because being added to repository??
        else if (type.equals(UPD_ADDED)) {
            status = JavaCvsStatusManager.LOCALLY_ADDED;
        }
        else if (type.equals(UPD_REMOVE)) {
            status = JavaCvsStatusManager.LOCALLY_REMOVED;
        }
        else if (type.equals(UPD_MODIFIED)) {
            status = JavaCvsStatusManager.LOCALLY_MODIFIED;
        }
        else if (type.equals(UPD_CONFLICT)) {
            status = JavaCvsStatusManager.CONFLICT;
        }
        else if (type.equals(UPD_UNKNOWN)) {
            // TODO unknown or Local???
            status = JavaCvsStatusManager.UNKNOWN;
        } else if (type.equals(UPD_MERGED)) {
            status = JavaCvsStatusManager.LOCALLY_MODIFIED;
        } else if (type.equals(DefaultFileInfoContainer.PERTINENT_STATE)) {
            status = null;
        }
        dir.put(updInfo, status);
    }
    
    private HashMap getDirMap(File parentFile) {
        HashMap dir = (HashMap)dirs.get(parentFile);
        if (dir == null) {
            dir = new HashMap(20);
            dirs.put(parentFile, dir);
        }
        return dir;
    }
    
    protected void prepareCache(File[] files, boolean recursive) {
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                File dir = null;
                if (files[i].isDirectory()) {
                    dir = files[i];
                } else {
                    dir = files[i].getParentFile();
                }
                createDirMap(dir, recursive);
            }
        }
    }
    
    private void createDirMap(File dir, boolean recursive) {
        getDirMap(dir);
        if (recursive) {
            File[] subs = dir.listFiles();
            if (subs != null && subs.length > 0) {
                for (int i = 0; i < subs.length; i++) {
                    if (subs[i].isDirectory()) {
                        createDirMap(subs[i], recursive);
                    }
                }
            }
        }
    }
    
    private File[] lockedFiles;
    private boolean lockedFilesRecursively;
    
    /**
     * Lock the set of files so that they can not be modified in the IDE.
     * This is necessary for commands, that make changes to the processed files.
     * It's crutial, that the file does not get modified twice - externally via
     * the update command and internally (e.g. through the Editor).
     * One MUST call {@link #unlockFilesToBeModified} after the command
     * finish.
     * @param files The array of files that are to be locked.
     * @param recursively Whether the files in directories should be locked recursively.
     */
    protected void lockFilesToBeModified(File[] files, boolean recursively) {
        if (files != null) {
            lockedFiles = files;
            lockedFilesRecursively = recursively;
            for (int i = 0; i < files.length; i++) {
                FileObject[] fos = org.openide.filesystems.FileUtil.fromFile(files[i]);
                for (int j = 0; j < fos.length; j++) {
                    FileSystem fs = (FileSystem) fos[j].getAttribute("VcsFileSystemAttributeIdentifier"); // VcsAttributes.VCS_NATIVE_FS
                    if (fs instanceof JavaCvsFileSystem) {
                        String nativePath = (String)fos[j].getAttribute("VcsFileSystemNativeFOPath"); // VcsAttributes.VCS_NATIVE_PACKAGE_NAME_EXT
                        ((JavaCvsFileSystem) fs).lockFilesToBeModified(nativePath, recursively);
                    }
                }
            }
        }
    }
    
    /**
     * Unlock the files that were previously locked by {@link #lockFilesToBeModified}
     * method. It's necessary to call this method after the command finish
     * so that the user can edit the files.
     */
    protected void unlockFilesToBeModified() {
        if (lockedFiles != null) {
            File[] files = lockedFiles;
            for (int i = 0; i < files.length; i++) {
                FileObject[] fos = org.openide.filesystems.FileUtil.fromFile(files[i]);
                for (int j = 0; j < fos.length; j++) {
                    FileSystem fs = (FileSystem) fos[j].getAttribute("VcsFileSystemAttributeIdentifier"); // VcsAttributes.VCS_NATIVE_FS
                    if (fs instanceof JavaCvsFileSystem) {
                        String nativePath = (String)fos[j].getAttribute("VcsFileSystemNativeFOPath"); // VcsAttributes.VCS_NATIVE_PACKAGE_NAME_EXT
                        ((JavaCvsFileSystem) fs).unlockFilesToBeModified(nativePath, lockedFilesRecursively);
                    }
                }
            }
        }
    }
    
    protected void updateCache(AddInformation addInfo) {
        HashMap dir = getDirMap(addInfo.getFile().getParentFile());
        String status;
        if (addInfo.isDirectory()) {
            String cacheFilePath = addInfo.getFile() + File.separator + 
                                   "CVS" + File.separator + "netbeans.cache"; //NOI18N
            File emptyCacheFile = new File(cacheFilePath);
            try {
                emptyCacheFile.createNewFile();
            } catch (IOException exc) {
                // just ignore, it will be created when te first command is run.
            }
            status = " "; // NOI18N
            newAddedDirs.add(addInfo.getFile());
            return;
        } else {
            String type = addInfo.getType();
            if (type.equals(AddInformation.FILE_RESURRECTED)) {
                status = JavaCvsStatusManager.UPTODATE;
            } else {
                status = JavaCvsStatusManager.LOCALLY_ADDED;
            }
        }
        dir.put(addInfo, status);
    }

    protected void updateCache(RemoveInformation removeInfo) {
        HashMap dir = getDirMap(removeInfo.getFile().getParentFile());
        String status;
        if (removeInfo.isRemoved()) {
            status = JavaCvsStatusManager.LOCALLY_REMOVED;
            dir.put(removeInfo, status);        
        }
    }

    protected void updateCache(CommitInformation commitInfo) {
        HashMap dir = getDirMap(commitInfo.getFile().getParentFile());
        String status;
        if (commitInfo.getType().equals(CommitInformation.REMOVED)) {
            dir.put(commitInfo, null);        
        } else {
            status = JavaCvsStatusManager.UPTODATE;
            dir.put(commitInfo, status);
        }
    }

    /** TEMPORARY solution until I write the correct stuff.
     *  It should be similar to the way refresh works in the cache.
     * However it should use less force than refresh.
     * checkServer(File rootDir, List returnedInfo)
     * 1. prepare and locks the rootDir recursively.
     * 2. perform the cache updating activities on known files.
     * 3. unlock the fileobjects.
     * this assumes I create a new Strategy for access into the cache.. COMMANDS = 6.
     *  (needs to be higher then Disk, but should IMHO load the disk level as well)
     */
/*    protected void checkServer(File[] filesToCheck, boolean recursive) {
            getFileSystem().doRefresh(filesToCheck, recursive);
    }
 */
    
    protected void updateCache(StatusInformation info) {
        HashMap dir = getDirMap(info.getFile().getParentFile());
        if (STATUS_NO_REVISION_CONTROL_FILE.equals(info.getRepositoryRevision()) &&
            (!org.netbeans.lib.cvsclient.file.FileStatus.ADDED.equals(info.getStatus()))) {
           dir.put(info, JavaCvsStatusManager.convertStatus(org.netbeans.lib.cvsclient.file.FileStatus.UNKNOWN));
           return;
        }
        dir.put(info, JavaCvsStatusManager.convertStatus(info.getStatus()));
    }
    
    protected void fireCacheEvents() {
        CacheHandler handler = CacheHandler.getInstance();
        JavaCvsCache cacheObject = (JavaCvsCache)handler.getCache(JavaCvsCache.JAVA_CACHE_NAME);
        HashSet set = new HashSet();
        File[] fls = getFiles();
        for (int index = 0; index < fls.length; index++) {
            File file = fls[index];
            if (file != null) {
                if (file.isDirectory()) {
                    set.add(file);
                } else {
                    set.add(file.getParentFile());
                }
//                System.out.println("added to set=" + file.getName());
            }
        }
        Iterator it = set.iterator();
        while (it.hasNext()) {
            File dir = (File)it.next();
//            System.out.println("looking for =" + dir.getName());
            CacheFile dirCache = handler.getCacheFile(dir,
                  CacheHandler.STRAT_NONE, JavaCvsCache.JAVA_CACHE_NAME);
            if (dirCache != null) {
                  cacheObject.fireCacheHandlerEvent(cacheObject.EVENT_ADD, dirCache);
//                    System.out.println("fired!");
            }
        }
        if(newAddedDirs.size() == 0)
            return;
        Iterator itDir = newAddedDirs.iterator();
        while(itDir.hasNext()){
            CacheFile dirCache = handler.getCacheFile((File)itDir.next(),
                  CacheHandler.STRAT_NONE, JavaCvsCache.JAVA_CACHE_NAME);
            if(dirCache != null){
                dirCache.setStatus(" ");
                cacheObject.fireCacheHandlerEvent(cacheObject.EVENT_ADD, dirCache);
            }
        }
    }

    
    protected void fireUpdateCache() {
        CacheHandler handler = CacheHandler.getInstance();
        JavaCvsCache cacheObject = (JavaCvsCache)handler.getCache(JavaCvsCache.JAVA_CACHE_NAME);
        CacheHandler.getInstance().registerCacheType("JavaCvs_Refreshing", new JavaCvsCache());  //NOI18N

        TreeSet drs = new TreeSet(dirs.keySet());
        Iterator it = drs.iterator();
        // iterate through the directories
        //        System.out.println("cacheObject=" + cacheObject);
        //        boolean dirToRefresh;
        StandardAdminHandler adminHandler = new StandardAdminHandler();
        while (it.hasNext()) {
            //            dirToRefresh = false;
            File dir = (File)it.next();
            if (dir == null) continue;
            CvsCacheDir dirCache = new CvsCacheDir("JavaCvs_Refreshing", dir); // NOI18N
//            System.out.println("dir=" + dir.getName());
            if (!isRefreshing()) {
                boolean ok = dirCache.readFromDisk();
//                System.out.println("read from disk = " + ok);
            }
            Entry[] entriesArray = null;
            try {
                entriesArray = adminHandler.getEntriesAsArray(dir);
                if (isFullEntriesUpdate()) {
                    updateFromEntries(dir, entriesArray, dirCache);
                }
            } catch (java.io.IOException exc) {
                entriesArray = new Entry[0];
            }
            
            HashMap fileList = (HashMap)dirs.get(dir);
            
            Iterator innerIt = fileList.keySet().iterator();
            while (innerIt.hasNext()) {
                // perform update
                FileInfoContainer info = (FileInfoContainer)innerIt.next();
                CvsCacheFile file = (CvsCacheFile)dirCache.getFile(info.getFile().getName());
                if (file != null) {
                    String status = (String)fileList.get(info);
                    file.setStatusNonModifying(status);
                    applyInfo(file, info, entriesArray);
                    if (status == null) {
                        // status is null->> means to remove the file
                        dirCache.removeFile(info.getFile().getName(), false);
                        //and probably from the original cache as well..
                        // no way to find out later when reloading..
                        CacheFile f2 =CacheHandler.getInstance().getCacheFile(dir, CacheHandler.STRAT_NONE, JavaCvsCache.JAVA_CACHE_NAME);
                        if (f2 != null && f2 instanceof CvsCacheDir) {
//                            System.out.println("removing obsolete cache file=" + info.getFile().getName());
                            CvsCacheDir cd2 = (CvsCacheDir)f2;
                            cd2.removeFile(info.getFile().getName(), false);
                        }
                    } 
                } else {
//                    if (info.getFile().isFile()) {
                        file = new CvsCacheFile("JavaCvs_Refreshing", info.getFile().getName()); // NOI18N
//                        dirCache.addFile(file, false);
                        String status = (String)fileList.get(info);
                        if (file != null && status != null) {
                            dirCache.addFile(file, false);
                            file.setStatusNonModifying(status);
                            applyInfo(file, info, entriesArray);
                        }
//                    }
                }
            } // end of file iteration within the directory
            dirCache.setAppliedLevel(CacheHandler.STRAT_DISK);
            dirCache.simpleWriteToDisk();

            CacheFile originalFile = handler.getCacheFile(dir, CacheHandler.STRAT_NONE, JavaCvsCache.JAVA_CACHE_NAME);
            if (originalFile != null && originalFile instanceof CvsCacheDir) {
                CvsCacheDir originalDir = (CvsCacheDir)originalFile;
                if (originalDir.getAppliedLevel() >= CacheHandler.STRAT_LOCAL) {
                    originalDir.setAppliedLevel(CacheHandler.STRAT_LOCAL);
//                    System.out.println("lowering level for dir.." + originalDir.getAbsolutePath());
                }
            }
            // release locks
//            cacheObject.removeLockedFileObjects(dir.getAbsolutePath());
        }
        dirs = new HashMap();
        fireCacheEvents();        
    }
    
    protected void updateFromEntries(File dir, Entry[] entries, CvsCacheDir cacheDir) {
        if (entries != null) {
            for (int i = 0; i < entries.length; i++) {
                Entry entry = entries[i];
                if (entry.isDirectory()) {
                    continue;
                }
                CvsCacheFile cFile = (CvsCacheFile)cacheDir.getFile(entry.getName());
                if (cFile == null) {
                    cFile = new CvsCacheFile("JavaCvs_Refreshing", entry.getName()); // NOI18N
                    cacheDir.addFile(cFile, false);
                }
                cFile.setRevision(entry.getRevision());
                cFile.setSticky(entry.getStickyInformation());
                if (!isRefreshing() && cFile.getStatus() == null || cFile.getStatus().equals(JavaCvsStatusManager.LOCAL)) {
                    //now we can try to guess what the status will be..
                    if (cFile.getRevision().startsWith("-")) { //NOI18N
                        cFile.setStatusNonModifying(JavaCvsStatusManager.LOCALLY_REMOVED);
                    } else if (cFile.getRevision().equals("0")) { //NOI18N
                        cFile.setStatusNonModifying(JavaCvsStatusManager.LOCALLY_ADDED);
                    } else {
                        if (entry.getLastModified() == null) {
                            continue;
                        }
                        long entryLast = entry.getLastModified().getTime()/1000;
                        File file = new File(cFile.getAbsolutePath());
                        if (!file.exists()) {
                            cFile.setStatusNonModifying(JavaCvsStatusManager.NEEDS_CHECKOUT);
                            continue;
                        }
                        long fileLast = file.lastModified() /1000;
                        if (entryLast == fileLast) {
                            cFile.setStatusNonModifying(JavaCvsStatusManager.UPTODATE);
                        } else {
                            cFile.setStatusNonModifying(JavaCvsStatusManager.LOCALLY_MODIFIED);
                        }
                    }
                }
            }
        }
    }

    private void applyInfo(CacheFile file, FileInfoContainer updInfo, Entry[] entries) {
        if (updInfo instanceof StatusInformation) {
            applyInfo(file, (StatusInformation)updInfo, entries);
            return;
        }
        if (updInfo.getClass().equals(DefaultFileInfoContainer.class)) {
            applyInfo(file, (DefaultFileInfoContainer)updInfo, entries);
            return;
        }
        if (updInfo instanceof CommitInformation) {
            applyInfo(file, (CommitInformation)updInfo, entries);
            return;
        }
        if (updInfo instanceof AddInformation) {
            applyInfo(file, (AddInformation)updInfo, entries);
            return;
        }
        if (updInfo instanceof RemoveInformation) {
            applyInfo(file, (RemoveInformation)updInfo, entries);
            return;
        }
    }    

    private void applyInfo(CacheFile file, DefaultFileInfoContainer updInfo, Entry[] entries) {
        Entry entry = null;
        for (int i = 0; i < entries.length; i++) {
            if (file.getName().equals(entries[i].getName())) {
                entry = entries[i];
                break;
            }
        }
        if (entry != null) {
            file.setRevision(entry.getRevision());
            file.setSticky(entry.getStickyInformation());
        }
    }
    
    private void applyInfo(CacheFile file, AddInformation addInfo, Entry[] entries) {
        if (addInfo.isDirectory()) return;
        if (addInfo.getType().equals(AddInformation.FILE_ADDED)) { // NOI18N
            file.setRevision(NbBundle.getBundle(CacheUpdatingFsCommand.class).getString("CacheUpdatingFsCommand.newRevision")); // NOI18N
            return;
        } 
        else if (addInfo.getType().equals("M")) { //NOI18N
            ((CvsCacheFile)file).setStatusNonModifying(JavaCvsStatusManager.LOCALLY_MODIFIED);
        }
        Entry entry = null;
        for (int i = 0; i < entries.length; i++) {
            if (file.getName().equals(entries[i].getName())) {
                entry = entries[i];
                break;
            }
        }
        if (entry != null) {
            file.setRevision(entry.getRevision());
            file.setSticky(entry.getStickyInformation());
        }
    }

    private void applyInfo(CacheFile file, RemoveInformation removeInfo, Entry[] entries) {
        if (!(file instanceof CacheDir)) {
            Entry entry = null;
            for (int i = 0; i < entries.length; i++) {
                if (file.getName().equals(entries[i].getName())) {
                    entry = entries[i];
                    break;
                }
            }
            if (entry != null) {
                file.setRevision(entry.getRevision());
            } else {
                file.setRevision("-"); //NOI18N
            }
/*            if (!file.getRevision().startsWith("-")) { // NOI18N
                file.setRevision("-" + file.getRevision()); // NOI18N
            }
 */
        }
    }

    private void applyInfo(CacheFile file, CommitInformation commitInfo, Entry[] entries) {
        String revision = commitInfo.getRevision();
        file.setRevision(revision);
        Entry entry = null;
        if (revision != null && revision.lastIndexOf('.') > 1) {
            // check only if the revision in question is on a branch..
            for (int i = 0; i < entries.length; i++) {
                if (file.getName().equals(entries[i].getName())) {
                    entry = entries[i];
                    if (entry.getStickyInformation() != null) {
                        file.setSticky(entry.getStickyInformation());
                    }
                    break;
                }
            }
        }
    }

    private void applyInfo(CacheFile file, StatusInformation info, Entry[] entries) {
        String rev = info.getWorkingRevision();
        if (rev != null && rev.length() == 0) {
            rev = null;
        }
        file.setRevision(rev);
        if (rev != null) {
            if ("New file!".equals(rev)) { //NOI18N
                file.setRevision(NbBundle.getBundle(CacheUpdatingFsCommand.class).getString("CacheUpdatingFsCommand.newRevision")); // NOI18N
            }
            if (rev.startsWith("No entry")) { //NOI18N
                file.setRevision(NbBundle.getBundle(CacheUpdatingFsCommand.class).getString("CacheUpdatingFsCommand.noWorkingEntry")); // NOI18N
            }
        }
        String sticky = info.getStickyTag();
        if (sticky != null && !sticky.equals("(none)")) { // NOI18N
            if (sticky.charAt(0) == '(' && sticky.charAt(sticky.length()) == ')') {
                sticky = sticky.substring(1, sticky.length() - 1);
            }
            int index = sticky.indexOf('(');
            if (index > 0) {
                sticky = sticky.substring(0, index - 1);
            }
            file.setSticky(sticky);
        }
        sticky = info.getStickyDate();
        if (sticky != null && !sticky.equals("(none)")) { // NOI18N
            if (sticky.charAt(0) == '(' && sticky.charAt(sticky.length()) == ')') {
                sticky = sticky.substring(1, sticky.length() - 1);
            }
            file.setSticky(sticky);
        }
    }
    
    /** Getter for property fullEntriesUpdate. This property is used for cases when no fileinfo 
     * object is generated, however the cache should update (cvs update -r )
     * We will use the CVS/Entries file for the cache update..
     * @return Value of property fullEntriesUpdate.
     */
    public boolean isFullEntriesUpdate() {
        return this.fullEntriesUpdate;
    }
    
    /** Setter for property fullEntriesUpdate. This property is used for cases when no fileinfo 
     * object is generated, however the cache should update (cvs update -r )
     * We will use the CVS/Entries file for the cache update..
     * @param fullEntriesUpdate New value of property fullEntriesUpdate.
     */
    public void setFullEntriesUpdate(boolean fullEntriesUpdate) {
        this.fullEntriesUpdate = fullEntriesUpdate;
    }
    
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 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.