/* * GCF - Generic Connection Framework for Java SE * GCF-Standard * * Copyright (c) 2007-2011 Marcel Patzlaff (marcel.patzlaff@gmail.com) * * This library is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ package com.github.gcf.io.jse; import java.io.File; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import javax.microedition.io.file.FileSystemListener; public final class FileSystemRegistryImpl { private final static long POLLING_INTERVAL= 2000L; private final class CheckerTask extends Thread { private boolean _cancelled= false; public void run() { while(true) { synchronized (this) { if(_cancelled) { break; } try { this.wait(POLLING_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); } } checkRoots(); } } protected void cancel() { synchronized (this) { _cancelled= true; this.notify(); } } } private final ArrayList _listeners= new ArrayList(); private HashSet _oldRoots= null; private CheckerTask _checkerTask= null; public synchronized boolean addFileSystemListener(FileSystemListener listener) { if(!_listeners.contains(listener)) { _listeners.add(listener); if(_listeners.size() == 1) { startPolling(); } return true; } return false; } public synchronized Enumeration listRoots() { return new FileEnumerator(File.listRoots(), true); } public synchronized boolean removeFileSystemListener(FileSystemListener listener) { if(_listeners.remove(listener)) { if(_listeners.size() <= 0) { stopPolling(); } return true; } return false; } protected synchronized void checkRoots() { if(_oldRoots == null) { return; } File[] roots= File.listRoots(); HashSet oldRoots= _oldRoots; HashSet newRoots= new HashSet(); for(int i= 0; i < roots.length; ++i) { File cf= roots[i]; if(!oldRoots.remove(cf)) { // new root notifyListeners(FileSystemListener.ROOT_ADDED, cf.getAbsolutePath()); } newRoots.add(cf); } if(oldRoots.size() > 0) { // removed roots Iterator iter= oldRoots.iterator(); while(iter.hasNext()) { File cf= (File) iter.next(); notifyListeners(FileSystemListener.ROOT_REMOVED, cf.getAbsolutePath()); } } _oldRoots= newRoots; } private void startPolling() { _oldRoots= new HashSet(); File[] roots= File.listRoots(); for(int i= 0; i < roots.length; ++i) { _oldRoots.add(roots[i]); } _checkerTask= new CheckerTask(); _checkerTask.start(); } private void stopPolling() { _checkerTask.cancel(); _checkerTask= null; _oldRoots= null; } private void notifyListeners(int state, String rootName) { for(int i= 0; i < _listeners.size(); ++i) { FileSystemListener l= (FileSystemListener) _listeners.get(i); l.rootChanged(state, rootName); } } }