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.vcscore.caching;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.netbeans.modules.vcscore.VcsFactory;
import org.netbeans.modules.vcscore.cache.CacheDir;
import org.netbeans.modules.vcscore.cache.CacheFile;
import org.netbeans.modules.vcscore.cache.FileSystemCache;
import org.netbeans.modules.vcscore.cache.CacheHandler;
import org.netbeans.modules.vcscore.util.*;
import org.netbeans.modules.vcscore.commands.VcsCommandExecutor;
import org.openide.ErrorManager;

/**
 * Directory in the cache.
 * @author Martin Entlicher
 */

/* The sibling is removed from the picture. But it should still work
 * because whenever cache file gets added, cache directory is written
 * to the disk which has complete list of files.
 */
public final class VcsCacheDir extends CacheDir {

    private volatile boolean beingLoaded = false;
    
    private boolean errorLineReported = false;
    private boolean errorWriteReported = false;
    private Object errorLock = new Object();
    
    /**
     * Create a new VCS cache directory.
     * @args cacheName the cache name
     * @args dirFile the cache directory file
     * @args rootNameLength the length of the name of the cache root
     * @args factory the VCS factory
     */
    public VcsCacheDir(String cacheName, File dirFile/*, int rootNameLength, VcsFactory factory*/) {
        super(cacheName, dirFile, new VcsCacheFile.VcsPersistentData(true));
        setLocal(true);
        setLoaded(false);
        // cacheFileName is used also for IO synchronization
        //cacheFileName = ((VcsCache) getCacheObject()).getCacheFileName(dirFile);
        //System.out.println("new VcsCacheDir("+dirFile+")");
        //setStatus(
        //this.rootNameLength = rootNameLength;
        //this.factory = factory;
    }
    
    VcsCacheDir(String cacheName, File dirFile, CacheFile.PersistentData data) {
        super(cacheName, dirFile, data);
        setLoaded(false);
        // cacheFileName is used also for IO synchronization
        //cacheFileName = ((VcsCache) getCacheObject()).getCacheFileName(dirFile);
        //System.out.println("new VcsCacheDir("+dirFile+") FROM DATA");
    }
    
    public String getPath () {
        //return ((VcsCache) getCacheObject()).getPath(dirFile);
        return dirFile.getAbsolutePath();
        //return dirName.substring(rootNameLength);
    }
    
    public File getFile() {
        return dirFile;
    }
    
    public String getFSPath() {
        return ((VcsCache) getCacheObject()).getPath(getFile());
    }
    
    private final Object loadedLock = new Object();

    public final boolean isLoaded () {
        return ((VcsCacheFile.VcsPersistentData) getPersistentData()).isLoaded();
    }
    
    protected final void setLoaded (boolean loaded) {
        synchronized (loadedLock) {
            ((VcsCacheFile.VcsPersistentData) getPersistentData()).setLoaded(loaded);
            loadedLock.notifyAll();
        }
    }
    
    public final boolean isBeingLoaded () {
        return this.beingLoaded;
    }
    
    protected final void setBeingLoaded (boolean beingLoaded) {
        this.beingLoaded = beingLoaded;
    }

    protected final void setLoadedRecursive (boolean loaded) {
        setLoaded(loaded);
        CacheDir[] subdirs = /*(VcsCacheDir[])*/ getSubDirs();
        for(int i = 0; i < subdirs.length; i++) {
            ((VcsCacheDir) subdirs[i]).setLoadedRecursive(loaded);
        }
    }
    
    /**
     * Wait until the directory is not loaded.
     * Blocks the current thread until {@link #isLoaded} is true.
     */
    public final void waitToLoad() throws InterruptedException {
        synchronized (loadedLock) {
            while (!isLoaded()) loadedLock.wait();
        }
    }
    
    public void add(CacheFile child) {
        if (child instanceof VcsCacheDir || child instanceof CacheDir) {
            addChildDir((CacheDir) child, true);
        } else {
            addFile(child, true);
        }
    }
    
    /** removes a file from the directory.
     * @param fireEvent - if true, fires EVENT_REMOVE event + sets this dir as modified.
     */
    public void removeFile(String flName, boolean fireEvent) {
        CacheFile file = getFile(flName);
        if (file != null) {
            super.removeFile(flName, fireEvent);
        }
    }
    
    protected void setParent(CacheDir par) {
        super.setParent(par);
        VcsCacheFile.VcsPersistentData vdata = (VcsCacheFile.VcsPersistentData) getPersistentData();
        if (par != null) {
            vdata.setCacheFileName(((VcsCacheDir) par).getCacheFileName());
        } else {
            vdata.setRemoved(true);
        }
        vdata.setModified(true); // I should be saved under my new parent
    }

    /**
     * Removes all files in this directory. No events are fired.
     */
    public void removeFiles() {
        synchronized (CHILD_FILES_LOCK) {
            CacheFile[] childFiles = getFiles();
            super.removeFiles();
        }
    }
    
    /** Get the names of all files and subdirectories */
    public String[] getFilesAndSubdirs() {
        String[] files = getFileNames();
        String[] dirs = getSubDirNames();
        String[] filesAndDirs = new String[files.length + dirs.length];
        System.arraycopy(files, 0, filesAndDirs, 0, files.length);
        System.arraycopy(dirs, 0, filesAndDirs, files.length, dirs.length);
        return filesAndDirs;
    }
    
    CacheFile getChildIfExists(String name) {
        CacheFile file = getFileIfExists(name);
        if (file == null) {
            file = getSubDirIfExists(name);
        }
        return file;
    }
    
    protected CacheFile createChildFromData(CacheFile.PersistentData data) {
        CacheFile file;
        if (data.isDirectory()) {
            file = new VcsCacheDir(getCacheName(), new File(getFile(), data.getName()), data);
            ((VcsCacheDir) file).readChildNamesFromDisk();
            //((CacheDir) file).readFromDisk(null); // It's necessary to initialize the directory content!
        } else {
            file = new VcsCacheFile(getCacheName(), data);
        }
        //file.setParent(this);
        return file;
    }
    
    /** Path string to the netbeans.cache file of this directory
     */
    protected String getCacheFileName() {
        return ((VcsCache) getCacheObject()).getCacheFileName(dirFile);
    }

    public void removeChildDir(String subdirName, boolean fireEvent) {
        CacheDir subDir = this.getSubDir(subdirName);
        if (subDir != null) {
            ((VcsCacheDir) subDir).deleteDiskCache(true);
            super.removeChildDir(subdirName, fireEvent);
        }
    }
    
    /**
     * Notify, that the content of the cache directory has changed and the cache
     * directory content is likely to be saved on disk.
     *
    protected void contentChangeddNotify() {
        writeToDisk();
    }
     */
    
    public void populateWithLocal(Object locker) {
        File[] subFiles = dirFile.listFiles();
        Set localDirNames = new HashSet();
        if (subFiles != null) {
            CacheHandler handler = CacheHandler.getInstance();
            for (int index = 0; index < subFiles.length; index++) {
                File oneFile = subFiles[index];
                if (oneFile == null) continue;
                if (oneFile.isDirectory()) {
                    localDirNames.add(oneFile.getName());
                    VcsCacheDir dir = (VcsCacheDir) getCacheObject().getDir(oneFile.getAbsolutePath());
                    if (dir == null) {
                        dir = (VcsCacheDir) ((VcsCache) getCacheObject()).lookupCacheDir(oneFile, true);//new VcsCacheDir(getCacheObject().getId(), oneFile);
                    }
                    if (dir == null) {
                        dir = new VcsCacheDir(getCacheObject().getId(), oneFile);
                        dir.setStatus(((VcsCache) getCacheObject()).getLocalFileStatus());
                        dir.setLocker(""); // NOI18N
                        dir.setRevision(""); // NOI18N
                        dir.setSticky(""); // NOI18N
                        dir.setAttr(""); // NOI18N
                        dir.setDate(""); // NOI18N
                        dir.setTime(""); // NOI18N
                        dir.setSize(0);
                        dir.setLocal(true);
                        this.addChildDir(dir, false);
                        dir.getPersistentData().setModified(false);
                    }
                    handler.addCacheLocker(locker, dir);
                } /*else {// I do not need local files in the cache !!
                 VcsCacheFile file = new VcsCacheFile(getCacheObject().getId(), oneFile.getName());
                 file.setStatus(((VcsCache) getCacheObject()).getLocalFileStatus());
                 this.addFile(file, false);
               }
                   */
            }
        }
        CacheDir[] subDirs = getSubDirs();
        for (int i = 0; i < subDirs.length; i++) {
            if (subDirs[i].isLocal() && !localDirNames.contains(subDirs[i].getName())) {
                this.removeChildDir(subDirs[i].getName(), false);
            }
        }
        
        setAppliedLevel(CacheHandler.STRAT_LOCAL);
        /*
        CacheDir cvsDir = getSubDir("CVS");
        if (cvsDir == null) {
          setLocal(true);
          setStatus(CacheFile.LOCAL);
        } else {
           setLocal(false);
           setStatus(" ");
        }
         */
    }
    
    /**
     * Refresh local files and let the non-local files unchanged.
     */
    public void refreshLocal(boolean recursively) {
        String[] mySubFiles = getFilesAndSubdirs();
        ArrayList lastLocal = new ArrayList(Arrays.asList(mySubFiles));
        for (int i = 0; i < lastLocal.size(); i++) {
            String fileName = (String) lastLocal.get(i);
            CacheFile file = getFile(fileName);
            if (file instanceof VcsCacheFile) {
                if (!((VcsCacheFile) file).isLocal()) lastLocal.remove(i--);
            } else if (file instanceof VcsCacheDir) {
                if (!((VcsCacheDir) file).isLocal()) lastLocal.remove(i--);
            }
        }
        File[] subFiles = dirFile.listFiles();
        if (subFiles != null) {
            for (int i = 0; i < subFiles.length; i++) {
                String name = subFiles[i].getName();
                if (lastLocal.contains(name)) {
                    lastLocal.remove(name);
                } else {
                    if (subFiles[i].isDirectory() && getSubDir(name) != null) {
                        VcsCacheDir dir = (VcsCacheDir) getCacheObject().getDir(subFiles[i].getAbsolutePath());
                        if (dir == null) {
                            dir = (VcsCacheDir) ((VcsCache) getCacheObject()).lookupCacheDir(subFiles[i], true);//new VcsCacheDir(getCacheObject().getId(), oneFile);
                        }
                        if (dir == null) {
                            dir = new VcsCacheDir(getCacheObject().getId(), subFiles[i]);
                            dir.setStatus(((VcsCache) getCacheObject()).getLocalFileStatus());
                            dir.setLocker(""); // NOI18N
                            dir.setRevision(""); // NOI18N
                            dir.setSticky(""); // NOI18N
                            dir.setAttr(""); // NOI18N
                            dir.setDate(""); // NOI18N
                            dir.setTime(""); // NOI18N
                            dir.setSize(0);
                            dir.setLocal(true);
                            this.addChildDir(dir, false);
                        }
                        dir.getPersistentData().setModified(false);
                    }
                }
            }
        }
        for (int i = 0; i < lastLocal.size(); i++) {
            String fileName = (String) lastLocal.get(i);
            CacheFile file = getFile(fileName);
            if (file != null) {
                removeFile(fileName, true);
            } else {
                CacheDir subDir = getSubDir(fileName);
                if (subDir != null) {
                    removeChildDir(fileName, true);
                }
            }
        }
        if (recursively) {
            CacheDir[] subDirs = getSubDirs();
            for (int i = 0; i < subDirs.length; i++) {
                ((VcsCacheDir) subDirs[i]).refreshLocal(recursively);
            }
        }
    }
    
    /*
    public void rename(String newPath) {
        String name = VcsUtilities.getFileNamePart(newPath);
        this.setName(name);
        setPath(newPath);
        for(int i = 0; i < subdirs.size(); i++) {
            VcsDir subdir = (VcsDir) subdirs.get(i);
            subdir.rename(newPath+"/"+subdir.getName());
        }
    }
     */
    
    /** Perform a shallow copy of this cache directory. Create a new instance
     * and copy all attributes. No children files or directories should be copied.
     *
    protected CacheDir shallowCopy() {
        System.out.println("shallowCopy("+getFile()+")");
        VcsCacheDir copy = new VcsCacheDir(getCacheName(), dirFile);
        copy.setAttr(getAttr());
        copy.setDate(getDate());
        copy.setIgnoreList(getIgnoreList());
        copy.setLocal(isLocal());
        copy.setLocker(getLocker());
        copy.setRevision(getRevision());
        copy.setSize(getSize());
        copy.setStatus(getStatus());
        copy.setSticky(getSticky());
        copy.setTime(getTime());
        return copy;
    }
     */
    
    /**
     * Read just names of children from the disk storage.
     */
    void readChildNamesFromDisk() {
        String cacheFilePath = getCacheFileName();
        if (cacheFilePath == null) return ;
        ArrayList files = new ArrayList();
        ArrayList dirs = new ArrayList();
        File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
        ArrayList cacheLines = new ArrayList();
        if (cacheFile.exists() && cacheFile.canRead()) {
            //System.err.println("readChildNamesFromDisk(): cacheFile = "+cacheFile);
            Object cacheFileLock = VcsCacheFile.VcsPersistentData.getFileAccessLock(cacheFile);
            try {
                synchronized (cacheFileLock) {
                    BufferedReader in = null;
                    try{
                        in = new BufferedReader(new FileReader(cacheFile));
                        String line = null;
                        while ((line = in.readLine()) != null) {
                            cacheLines.add(line);
                        }
                    } catch (IOException e) {
                    } finally {
                        if (in != null) { 
                            try {
                                in.close();
                            } catch (IOException exc) {}
                            in = null;
                        }
                    }
                }
            } finally {
                VcsCacheFile.VcsPersistentData.releaseFileAccessLock(cacheFile, cacheFileLock);
            }
        }
        if (cacheLines.size() > 0) {
            for (int i = 0; i < cacheLines.size(); i++) {
                String line = (String) cacheLines.get(i);
                boolean[] isDir = new boolean[1];
                try {
                    String name = VcsCacheFile.readFileCacheName(line, getCacheName(), isDir);
                    if (isDir[0]) {
                        dirs.add(name);
                    } else {
                        files.add(name);
                    }
                } catch (IllegalArgumentException iaex) {
                    synchronized (errorLock) {
                        if (!errorLineReported) {
                            ErrorManager.getDefault().notify(org.openide.ErrorManager.WARNING,
                                ErrorManager.getDefault().annotate(iaex, "Line read: '"+line+"'"));
                            errorLineReported = true;
                        }
                    }
                }
            }
            int fs = files.size();
            int ds = dirs.size();
            if ((fs + ds) > 0) {
                addChildNames((String[]) files.toArray(new String[fs]), (String[]) dirs.toArray(new String[ds]));
            }
        }
        //System.err.println("readChildNamesFromDisk() = "+this);
    }
    
    public boolean readFromDisk(Object locker) {
        boolean isOk = false;
        String cacheFilePath = getCacheFileName();
        if (cacheFilePath == null) return false;
        ArrayList files = new ArrayList();
        File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
        ArrayList cacheLines = new ArrayList();
        if (cacheFile.exists() && cacheFile.canRead()) {
            //System.err.println("readFromDisk(): cacheFile = "+cacheFile+", does"+(cacheFile.exists() ? "" : " not")+" exist");
            Object cacheFileLock = VcsCacheFile.VcsPersistentData.getFileAccessLock(cacheFile);
            try {
                synchronized (cacheFileLock) {
                    BufferedReader in = null;
                    try{
                        in = new BufferedReader(new FileReader(cacheFile));
                        String line = null;
                        while ((line = in.readLine()) != null) {
                            cacheLines.add(line);
                        }
                        in.close();
                        isOk= true;
                        //return isOk;
                    } catch (IOException e){
                        ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ErrorManager.getDefault().annotate(e,"readDirFromDiskCache() failed")); // NOI18N
                    } finally {
                        if (in != null) { 
                            try {
                                in.close();
                            } catch (IOException exc) {}
                            in = null;
                        }
                    }
                }
            } finally {
                VcsCacheFile.VcsPersistentData.releaseFileAccessLock(cacheFile, cacheFileLock);
            }
        }
        if (cacheLines.size() > 0) {
            for (int i = 0; i < cacheLines.size(); i++) {
                String line = (String) cacheLines.get(i);
                try {
                    CacheFile file = VcsCacheFile.readFileCache(line, getCacheName(), getFile());
                    files.add(file);
                } catch (IllegalArgumentException iaex) {
                    synchronized (errorLock) {
                        if (!errorLineReported) {
                            ErrorManager.getDefault().notify(org.openide.ErrorManager.WARNING,
                                ErrorManager.getDefault().annotate(iaex, "Line read: '"+line+"'"));
                            errorLineReported = true;
                        }
                    }
                }
            }
        }
        CacheHandler handler = CacheHandler.getInstance();
        for (Iterator filesIt = files.iterator(); filesIt.hasNext(); ) {
            CacheFile file = (CacheFile) filesIt.next();
            add(file);
            file.getPersistentData().setModified(false);
            handler.addCacheLocker(locker, file);
            if (file instanceof CacheDir) getCacheObject().registerDir((CacheDir) file);
        }
        if (isOk) {
            setLoaded(true);
            setAppliedLevel(CacheHandler.STRAT_DISK);
            setModifiedContent(false);
        }
        setLocal(false);
        //System.err.println("VcsCacheDir.readFromDisk = "+this);
        return isOk;
    }
    
    /**
     * Read just one file from disk cache. This method must not return null.
     * If the file does not exist in the disk cache, create a local file.
     * @param name The file name
     * @return A cache file.
     */
    protected CacheFile readFileFromDisk(String name) {
        String cacheFilePath = getCacheFileName();
        //System.err.println("FILE ("+getFile()+").readFileFromDisk("+name+")");
        VcsCacheFile file = null;
        if (cacheFilePath != null) {
            File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
            if (cacheFile.exists() && cacheFile.canRead()) {
                Object cacheFileLock = VcsCacheFile.VcsPersistentData.getFileAccessLock(cacheFile);
                try {
                    synchronized (cacheFileLock) {
                        BufferedReader in = null;
                        try {
                            in = new BufferedReader(new FileReader(cacheFile));
                            //do the acutal read of the file from the disk 
                            //
                            file = doReadFileFromDisk(name, in);
                            //return isOk;
                        } catch (IOException e){
                            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
                        } finally {
                            if (in != null) { 
                                try {
                                    in.close();
                                } catch (IOException exc) {}
                            }
                        }
                    }
                } finally {
                    VcsCacheFile.VcsPersistentData.releaseFileAccessLock(cacheFile, cacheFileLock);
                }
            }
        }
        if (file == null) {
            file = new VcsCacheFile(getCacheName(), name);
            file.setStatus(((VcsCache) getCacheObject()).getLocalFileStatus());
            file.setLocal(true);
        }
        //System.err.println("  readFileFromDisk = "+file);
        return file;
    }
    
     /**
     * The routine has the same function as the readFileFromDisk(String name),
     * except that the cache file reader is passed as an argument. Added for
     * efficiency.
     * @param name The file name
     * @param in the cache file reader (can be null).
     * @return A cache file.
     */
    protected CacheFile readFileFromDisk(String name, BufferedReader in) {
        String cacheFilePath = getCacheFileName();
        //System.err.println("FILE ("+getFile()+").readFileFromDisk("+name+")");
        VcsCacheFile file = null;
        if (in != null && cacheFilePath != null) {
            File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
            if (cacheFile.exists() && cacheFile.canRead()) {
                Object cacheFileLock = VcsCacheFile.VcsPersistentData.getFileAccessLock(cacheFile);
                try {
                    synchronized (cacheFileLock) {
                        try {
                            file = doReadFileFromDisk(name, in);
                        } catch (IOException e){
                            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
                        } 
                    }
                } finally {
                    VcsCacheFile.VcsPersistentData.releaseFileAccessLock(cacheFile, cacheFileLock);
                }
            }
        }
        if (file == null) {
            file = new VcsCacheFile(getCacheName(), name);
            file.setStatus(((VcsCache) getCacheObject()).getLocalFileStatus());
            file.setLocal(true);
        }
        //System.err.println("  readFileFromDisk = "+file);
        return file;
    }
    
     /**
     * Read the cache file.
     * @param name The file name
     * @param in the cache file reader
     * @return A cache file.
     */
    private VcsCacheFile doReadFileFromDisk(String name,  BufferedReader in) throws IOException {
        VcsCacheFile file = null;
        String line = null;
        while ((line = in.readLine()) != null) {
            try {
                String[] elements = StatusFormat.getElementsFromLine(line);
                String fileName = elements[StatusFormat.ELEMENT_INDEX_FILE_NAME];
                if (name.equals(fileName)) {
                    file = new VcsCacheFile(getCacheName(), name);
                    RefreshCommandSupport.matchToFile(elements, file);
                    file.setLocal(false);
                    file.setParent(this);
                    file.getPersistentData().setModified(false);
                    break;
                }
            } catch (IllegalArgumentException iaex) {
                synchronized (errorLock) {
                    if (!errorLineReported) {
                        ErrorManager.getDefault().notify(org.openide.ErrorManager.WARNING,
                        ErrorManager.getDefault().annotate(iaex, "Line read: '"+line+"'"));
                        errorLineReported = true;
                    }
                }
            }
        }
        return file;
    }
        
    /**
     * Read just one directory from disk cache. This method must not return null.
     * If the directory does not exist in the disk cache, create a local dir.
     * @param name The directory name
     * @return A cache directory.
     */
    protected CacheDir readDirFromDisk(String name) {
        String cacheFilePath = getCacheFileName();
        //System.err.println("DIR ("+getFile()+").readDirFromDisk("+name+")");
        VcsCacheDir dir = null;
        if (cacheFilePath != null) {
            File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
            if (cacheFile.exists() && cacheFile.canRead()) {
                Object cacheFileLock = VcsCacheFile.VcsPersistentData.getFileAccessLock(cacheFile);
                try {
                    synchronized (cacheFileLock) {
                        String dirName = name + "/"; // NOI18N
                        BufferedReader in = null;
                        try {
                            in = new BufferedReader(new FileReader(cacheFile));
                            String line = null;
                            while ((line = in.readLine()) != null) {
                                try {
                                    String[] elements = StatusFormat.getElementsFromLine(line);
                                    String fileName = elements[StatusFormat.ELEMENT_INDEX_FILE_NAME];
                                    if (dirName.equals(fileName)) {
                                        dir = new VcsCacheDir(getCacheName(), new java.io.File(getFile(), name));
                                        dir.setName(name);
                                        RefreshCommandSupport.matchToFile(elements, dir);
                                        dir.setLocal(false);
                                        dir.setParent(this);
                                        dir.getPersistentData().setModified(false);
                                        break;
                                    }
                                } catch (IllegalArgumentException iaex) {
                                    synchronized (errorLock) {
                                        if (!errorLineReported) {
                                            ErrorManager.getDefault().notify(org.openide.ErrorManager.WARNING,
                                                ErrorManager.getDefault().annotate(iaex, "Line read: '"+line+"'"));
                                            errorLineReported = true;
                                        }
                                    }
                                }
                            }
                            in.close();
                            //return isOk;
                        } catch (IOException e){
                            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
                        } finally {
                            if (in != null) { 
                                try {
                                    in.close();
                                } catch (IOException exc) {}
                            }
                        }
                    }
                } finally {
                    VcsCacheFile.VcsPersistentData.releaseFileAccessLock(cacheFile, cacheFileLock);
                }
            }
        }
        if (dir == null) {
            dir = new VcsCacheDir(getCacheName(), new java.io.File(getFile(), name));
            dir.setStatus(((VcsCache) getCacheObject()).getLocalFileStatus());
            dir.setLocal(true);
            dir.setParent(this);
            dir.getPersistentData().setModified(false);
        } else {
            dir.readChildNamesFromDisk();
        }
        //System.err.println("  readDirFromDisk = "+dir);
        return dir;
    }
    
    public void writeToDisk() {
        //System.err.println("writeToDisk(): file = "+getCacheFileName());
        //System.err.println("writeToDisk(): dir = "+this);
        String cacheFilePath = getCacheFileName();
        if (cacheFilePath == null) return ;
        CacheFile[] files = getFiles();
        CacheDir[] dirs = getSubDirs();
        boolean ok = false;
        File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
        Object cacheFileLock = VcsCacheFile.VcsPersistentData.getFileAccessLock(cacheFile);
        try {
            synchronized (cacheFileLock) {
                BufferedWriter out = null;
                try {
                    File cacheDir = cacheFile.getParentFile();
                    if (!cacheDir.exists()) cacheDir.mkdirs();
                    try {
                        cacheFile.createNewFile();
                    } catch (IOException ioexc) {
                        synchronized (errorLock) {
                            if (!errorWriteReported) {
                                ErrorManager.getDefault().notify(
                                    ErrorManager.getDefault().annotate(ioexc,
                                        "Exception when trying to create a new file '"+cacheFile.getAbsolutePath()));
                                errorWriteReported = true;
                            }
                        }
                    }
                    out = new BufferedWriter(new FileWriter(cacheFile));
                    // write files first
                    //Collection files = new ArrayList(cachedFiles.values());
                    for (int i = 0; i < files.length; i++) {
                        if (!((VcsCacheFile) files[i]).isLocal()) {
                            String line = ((VcsCacheFile.VcsPersistentData) files[i].getPersistentData()).writeLineToDisk();
                            if (line.length() > 0) {
                                out.write(line);
                                out.newLine();
                            }
                        }
                        files[i].getPersistentData().setModified(false);
                    }
                    // then directories
                    //Collection dirs = new ArrayList(childDirs.values());
                    for (int i = 0; i < dirs.length; i++) {
                        if (!((VcsCacheDir) dirs[i]).isLocal()) {
                            String line = ((VcsCacheFile.VcsPersistentData) dirs[i].getPersistentData()).writeLineToDisk();
                            if (line.length() > 0) {
                                out.write(line);
                                out.newLine();
                            }
                        }
                        dirs[i].getPersistentData().setModified(false);
                    }
                    //System.out.println("WRITTEN:\n FILES = "+new ArrayList(Arrays.asList(files))+"\n DIRS = "+new ArrayList(Arrays.asList(dirs)));
                    //System.err.println("WRITTEN:\n FILES = "+new ArrayList(Arrays.asList(files))+"\n DIRS = "+new ArrayList(Arrays.asList(dirs)));
                    out.flush();
                    ok = true;
                } catch (IOException exc) {
                    synchronized (errorLock) {
                        if (!errorWriteReported) {
                            ErrorManager.getDefault().notify(exc);
                            errorWriteReported = true;
                        }
                    }
                } finally {
                    try {
                        if (out != null) out.close();
                    } catch (IOException e) {
                        synchronized (errorLock) {
                            if (!errorWriteReported) {
                                ErrorManager.getDefault().notify(e);
                                errorWriteReported = true;
                            }
                        }
                    }
                }
            }
        } finally {
            VcsCacheFile.VcsPersistentData.releaseFileAccessLock(cacheFile, cacheFileLock);
        }
        if (ok) {
            setModifiedContent(false);
            // Write also my data to the parent dir if necessary.
            try {
                getPersistentData().writeToDisk();
            } catch (IOException ioex) {
                synchronized (errorLock) {
                    if (!errorWriteReported) {
                        ErrorManager.getDefault().notify(ioex);
                        errorWriteReported = true;
                    }
                }
            }
            //getPersistentData().setModified(false);
        }
    }
    
    public String writeLineToDisk() {
        String[] elements = RefreshCommandSupport.makeElements(this);
        elements[StatusFormat.ELEMENT_INDEX_FILE_NAME] += "/"; // NOI18N
        return StatusFormat.getLineFromElements(elements);
    }
    
    private void deleteDiskCache(boolean recursive) {
        String cacheFilePath = getCacheFileName();
        if (cacheFilePath == null) return ;
        File cacheFile = new File(cacheFilePath); // the actual netbeans.cache file
        cacheFile.delete();
        if (recursive) {
            CacheDir[] subDirs = getSubDirs();
            for (int i = 0; i < subDirs.length; i++) {
                ((VcsCacheDir) subDirs[i]).deleteDiskCache(recursive);
            }
        }
    }

    public void checkServer(Object locker) {
        boolean runReader;
        synchronized (this) {
            if (isBeingLoaded()) return;
            // thread has to start here..
            if (!isLoaded() || !isLocal()) {
                setAppliedLevel(CacheHandler.STRAT_DISK);
                runReader = true;
            } else runReader = false;
        }
        if (runReader) {
            VcsCache cache = (VcsCache) getCacheObject();
            //cache.prepareCache(new File(this.getAbsolutePath()), false, CacheHandler.STRAT_REFRESHING);
            //System.out.println("VcsCacheDir.checkServer(): dir = "+this.toString());
            //cache.fireCacheHandlerEvent(FileSystemCache.EVENT_CHANGED, this);
            //cache.lockFileObjects(this, false);
            cache.runVcsDirReader(this, locker);
        }
    }

    /** Associates with the STRAT_REFRESH_RECURS, if that strategy is requested this method is called.
     * do a recursive server check. Connect to server and request status update etc..
     * Note: within this method implementations need to make sure
     */
    public void checkServerRecursive(Object locker) {
        boolean runReader;
        synchronized (this) {
            if (isBeingLoaded()) return;
            // thread has to start here..
            if (!isLoaded() || !isLocal()) {
                setAppliedLevel(CacheHandler.STRAT_DISK);
                runReader = true;
            } else runReader = false;
        }
        if (runReader) {
            VcsCache cache = (VcsCache) getCacheObject();
            //cache.lockFileObjects(this, true);
            //cache.prepareCache(new File(this.getAbsolutePath()), true, CacheHandler.STRAT_REFRESHING);
            //cache.fireCacheHandlerEvent(FileSystemCache.EVENT_CHANGED_RECURSIVELY, this);
            cache.runVcsDirReaderRecursive(this, locker);
        }
    }    

    /**
     * This method is called to create an ignore list when it is needed.
     * Call setIgnoreList() method to set the created ignore list.
     */
    protected void createIgnoreList() {
        CacheDir parent = getParent();
        //if (parent != null && !parent.isIgnoreListSet()) return ;
        VcsCache cache = (VcsCache) getCacheObject();
        cache.createIgnoreList(this, (parent == null) ? null : parent.getIgnoreList());
    }


    // dev support ~~~~~~~~~~~~~~~~~~~~~

    public String toString() {
        String[] fileNames = getFileNames();
        //String[] fileNames = new String[files.length];
        //for (int i = 0; i < files.length; i++) fileNames[i] = files[i].getName();
        //CacheDir[] dirs = getSubDirs();
        String[] dirNames = getDirNames();//new String[dirs.length];
        //for (int i = 0; i < dirs.length; i++) dirNames[i] = dirs[i].getName();
        String strOut =  "VcsDir[name='"+getName()+"',status="+getStatus()+", file = "+getFile()+ // NOI18N
                         "\n files="+VcsUtilities.arrayToString(fileNames)+",\n subdir="+VcsUtilities.arrayToString(dirNames)+"\n isLocal = "+isLocal()+" isLoaded = "+isLoaded()+" isBeingLoaded = "+isBeingLoaded()+"]"; // NOI18N
        /*
        if (getFiles() != null) {
            for (int i = 0; i < getFiles().length; i++) {
                strOut += "\nSubFile = " + getFiles()[i].toString(); // NOI18N
            }
        }/*
        if (getSubDirs() != null) {
            for (int i = 0; i < getSubDirs().length; i++) {
                strOut += "\nSubDir = " + getSubDirs()[i].toString();
            }
        }
         */
        return strOut;
    }

    /* TEST METHOD ONLY *
    protected void finalize() throws Throwable {
        System.out.println("Directory "+getFile()+"  FINALIZED");
    }
     */

    /**
     * Until marked as loaded there is only lightweight skeleton
     * in memory that is lazily filled on demand. Skip check
     * in such case.
     */
    public boolean directoriesConsistencyInvariant() {
        if (isLoaded()) return super.directoriesConsistencyInvariant();
        return true;
    }

}
... 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.