/* * Copyright 2011 Uwe Krueger. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mandelsoft.mand.scan; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.mandelsoft.io.FolderLock; import java.util.HashMap; /** * * @author Uwe Krüger */ public class MandelFolder extends FolderLock { static public boolean debug=false; static private Map<File,MandelFolder> map=new HashMap<File,MandelFolder>(); synchronized public static MandelFolder getMandelFolder(File f) throws IOException { f=f.getCanonicalFile(); if (debug) System.out.println("%%% get mandel folder "+f); MandelFolder m=map.get(f); if (m==null) { if (debug) System.out.println(" create new mandel folder"); m=new MandelFolder(f); map.put(f,m); } return m; } private MandelFolderCache cache; public MandelFolder(File f) throws IOException { super(f); if (!f.isDirectory()) throw new IOException(f+" is no directory"); lock(); try { if (MandelFolderCache.isCached(f)) { cache=new MandelFolderCache(f); } } finally { releaseLock(); } } synchronized public MandelFolderCache getCache() { return cache; } synchronized public boolean hasCache() { return cache!=null; } synchronized void createCache() throws IOException { if (cache==null) { cache=new MandelFolderCache(this.getFolder()); cache.recreate(); } } synchronized public void recreate() throws IOException { if (cache!=null) { lock(); try { cache.recreate(); } finally { releaseLock(); } } } public boolean remove(String name) throws IOException { return remove(new File(getFolder(),name)); } synchronized public boolean remove(File f) throws IOException { f=f.getCanonicalFile(); if (!f.getParentFile().equals(getFolder())) { throw new IllegalArgumentException(f+" not in directory"); } lock(); try { if (f.delete()) { _handleRemoved(f); return true; } return false; } finally { releaseLock(); } } synchronized protected void handleRemoved(File f) throws IOException { lock(); try { _handleRemoved(f); } finally { releaseLock(); } } protected void _handleRemoved(File f) throws IOException { boolean full=false; if (cache!=null) { full=cache.update(); if (cache.removeFile(f)) cache.write(); } if (full) { folderUpdated(getFolder()); } else { removeMandelFile(f); } } public boolean moveToLocal(File f) throws IOException { return renameTo(f,new File(getFolder(),f.getName())); } public boolean renameTo(File f, String name) throws IOException { return renameTo(f,new File(getFolder(),name)); } public boolean renameTo(File f, File dst) throws IOException { MandelFolder src=null; dst=dst.getCanonicalFile(); if (!dst.getParentFile().equals(getFolder())) { throw new IllegalArgumentException(dst+" not in directory"); } File old=f.getCanonicalFile(); try { synchronized (this) { lock(); try { if (f.renameTo(dst)) { if (debug) System.out.println("rename successful "+dst); if (old.getParentFile().equals(getFolder())) { if (debug) System.out.println("remove from current"); _handleRemoved(old); } else { if (debug) System.out.println("remove from other "+old.getParentFile()); src=getMandelFolder(old.getParentFile()); //src._handleRemoved(old); } _handleAdded(dst); return true; } return false; } finally { releaseLock(); } } } finally { if (debug) System.out.println("propagate remove from "+src); if (src!=null) { src.handleRemoved(old); } } } protected void _handleAdded(File f) throws IOException { boolean full=false; MandelFolderCache.Entry e=null; if (cache!=null) { full=cache.update(); e=cache.addFile(f); if (e!=null) { cache.write(); } } if (full) { folderUpdated(getFolder()); } else { addMandelFile(f, e); } } synchronized public void add(File f) throws IOException { boolean full=false; f=f.getCanonicalFile(); if (!f.getParentFile().equals(getFolder())) { throw new IllegalArgumentException(f+" not in directory"); } lock(); try { _handleAdded(f); } finally { releaseLock(); } } @Override public String toString() { return getFolder().toString(); } ////////////////////////////////////////////////////////////////////////// // events private List<MandelFolderListener> listenerList=new ArrayList<MandelFolderListener>(); synchronized public void addMandelFolderListener(MandelFolderListener l) { listenerList.add(l); } synchronized public void removeMandelFolderListener(MandelFolderListener l) { listenerList.remove(l); } synchronized public MandelFolderListener[] getMandelFolderListeners() { return listenerList.toArray(new MandelFolderListener[listenerList.size()]); } protected void addMandelFile(File f, MandelFolderCache.Entry e) { for (MandelFolderListener l:listenerList) { l.addMandelFile(f,e); } } protected void removeMandelFile(File f) { //System.out.println("propagate file remove "+listenerList.size()); for (MandelFolderListener l:listenerList) { l.removeMandelFile(f); } } protected void folderUpdated(File f) { for (MandelFolderListener l:listenerList) { l.folderUpdated(f); } } ////////////////////////////////////////////////////////////////////////// // util static public class Util { public static void add(File f) throws IOException { MandelFolder mf=getMandelFolder(f.getParentFile()); mf.add(f); } public static boolean delete(File f) throws IOException { MandelFolder mf=getMandelFolder(f.getParentFile()); return mf.remove(f); } public static boolean renameTo(File s, File d) throws IOException { MandelFolder mf=getMandelFolder(d.getParentFile()); return mf.renameTo(s,d); } } //////////////////////////////////////////////////////////////////// static public void main(String[] args) { File n=new File("."); if (args.length>0) n=new File(args[0]); try { MandelFolder f=getMandelFolder(n); f.createCache(); } catch (IOException ex) { System.out.println("cannot handle folder "+n+": "+ex); } } }