001    package org.nanocontainer.deployer;
002    
003    import org.apache.commons.vfs.FileObject;
004    import org.apache.commons.vfs.FileSystemException;
005    import org.apache.commons.vfs.FileSystemManager;
006    import org.apache.commons.vfs.FileType;
007    
008    import java.util.ArrayList;
009    import java.util.Arrays;
010    import java.util.Iterator;
011    import java.util.List;
012    
013    /**
014     * @author Aslak Hellesøy
015     * @version $Revision: 2343 $
016     */
017    public class DifferenceAnalysingFolderContentHandler implements FolderContentHandler {
018        private final FileObject folder;
019        private final FileSystemManager fileSystemManager;
020    
021        private FileObject[] lastChildren = new FileObject[0];
022    
023        public DifferenceAnalysingFolderContentHandler(FileObject folder, FileSystemManager fileSystemManager) {
024            this.folder = folder;
025            this.fileSystemManager = fileSystemManager;
026        }
027    
028        public void setCurrentChildren(FileObject[] currentChildren) {
029            List current = Arrays.asList(currentChildren);
030            List last = Arrays.asList(lastChildren);
031    
032            fireFolderAddedMaybe(current, last);
033            fireFolderRemovedMaybe(current, last);
034    
035            lastChildren = currentChildren;
036        }
037    
038        private void fireFolderAddedMaybe(List current, List last) {
039            current = new ArrayList(current);
040            last = new ArrayList(last);
041    
042            current.removeAll(last);
043            for (Iterator iterator = current.iterator(); iterator.hasNext();) {
044                FileObject fileObject = (FileObject) iterator.next();
045                FileObject folderObject = convertToFolder(fileObject);
046                if (folderObject != null && folderListener != null) {
047                    folderListener.folderAdded(folderObject);
048                }
049            }
050        }
051    
052        private void fireFolderRemovedMaybe(List current, List last) {
053            current = new ArrayList(current);
054            last = new ArrayList(last);
055    
056            last.removeAll(current);
057            for (Iterator iterator = last.iterator(); iterator.hasNext();) {
058                FileObject fileObject = (FileObject) iterator.next();
059                FileObject folderObject = convertToFolder(fileObject);
060                if (folderObject != null && folderListener != null) {
061                    folderListener.folderRemoved(fileObject);
062                }
063            }
064        }
065    
066        private FileObject convertToFolder(FileObject fileObject) {
067            FileObject result = null;
068            try {
069                if (fileObject.getType().equals(FileType.FOLDER)) {
070                    result = fileObject;
071                } else if (fileObject.getType().equals(FileType.FILE)) {
072                    String extension = fileObject.getName().getExtension();
073                    if (extension.equals("zip") || extension.equals("jar")) {
074                        String url = "zip:" + fileObject.getURL().getFile();
075                        result = fileSystemManager.resolveFile(url);
076                    }
077                }
078            } catch (FileSystemException ignore) {
079            }
080            return result;
081        }
082    
083        public FileObject getFolder() {
084            return folder;
085        }
086    
087        private FolderListener folderListener;
088    
089        public void addFolderListener(FolderListener folderListener) {
090            if (this.folderListener != null) {
091                throw new IllegalStateException(FolderListener.class.getName() + " already added");
092            }
093            this.folderListener = folderListener;
094        }
095    
096        public void removeFolderListener(DeployingFolderListener deployingFolderListener) {
097            this.folderListener = null;
098        }
099    }