001: /*
002: *
003: *
004: * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights
005: * Reserved. Use is subject to license terms.
006: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License version
010: * 2 only, as published by the Free Software Foundation.
011: *
012: * This program is distributed in the hope that it will be useful, but
013: * WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License version 2 for more details (a copy is
016: * included at /legal/license.txt).
017: *
018: * You should have received a copy of the GNU General Public License
019: * version 2 along with this work; if not, write to the Free Software
020: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
021: * 02110-1301 USA
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
024: * Clara, CA 95054 or visit www.sun.com if you need additional
025: * information or have any questions.
026: */
027:
028: /*
029: * Copyright (C) 2002-2003 PalmSource, Inc. All Rights Reserved.
030: */
031:
032: package javax.microedition.io.file;
033:
034: import com.sun.midp.io.j2me.file.RootCache;
035: import com.sun.midp.io.j2me.file.Protocol;
036: import java.util.Enumeration;
037: import java.util.Vector;
038:
039: import com.sun.midp.security.Permissions;
040: import com.sun.midp.midlet.MIDletSuite;
041: import com.sun.midp.midlet.Scheduler;
042: import java.util.NoSuchElementException;
043: import com.sun.midp.security.*;
044:
045: /**
046: * This class is defined by the JSR-75 specification
047: * <em>PDA Optional Packages for the J2ME™ Platform</em>
048: */
049: // JAVADOC COMMENT ELIDED
050: public class FileSystemRegistry {
051:
052: /** Currently registered listeners. */
053: private static Vector fileSystemListeners = new Vector(2);
054:
055: /**
056: * Determines whether internal filesystem events listener
057: * is created and registered.
058: */
059: private static boolean isListenerRegistered = false;
060:
061: /** Constructor. */
062: FileSystemRegistry() {
063: }
064:
065: // JAVADOC COMMENT ELIDED
066: public static boolean addFileSystemListener(
067: FileSystemListener listener) {
068: if (listener == null) {
069: throw new NullPointerException();
070: }
071:
072: checkReadPermission();
073:
074: // Create and register file system events listener in MIDP event system
075: // (if there is no registered yet)
076: if (!isListenerRegistered) {
077: // Create root cache object and fill it's internal cache with
078: // currently mounted roots.
079: // Cache is used to determine which roots were mounted/unmounted
080: // if EventTypes.FC_DISKS_CHANGED_EVENT event arrives.
081: RootCache.initialize();
082:
083: FileSystemEventHandler
084: .setListener(new FileSystemEventHandler());
085: isListenerRegistered = true;
086: }
087:
088: fileSystemListeners.addElement(listener);
089:
090: return true;
091: }
092:
093: // JAVADOC COMMENT ELIDED
094: public static boolean removeFileSystemListener(
095: FileSystemListener listener) {
096: if (listener == null) {
097: throw new NullPointerException();
098: }
099:
100: return fileSystemListeners.removeElement(listener);
101: }
102:
103: // JAVADOC COMMENT ELIDED
104: public static Enumeration listRoots() {
105: checkReadPermission();
106: // retrieve up-to-date list of mounted roots
107: return Protocol.listRoots().elements();
108: }
109:
110: /**
111: * Gets a list of cached file system roots without checking permissions.
112: * @return Enumeration of roots
113: */
114: static Enumeration listCachedRoots() {
115: /** List of file system roots. */
116: return new Enumeration() {
117: /** Array of root pathnames. */
118: String[] roots = RootCache.getInstance().getRoots();
119: /** Current index int the enumeration. */
120: int index = 0;
121:
122: /**
123: * Checks if more data available.
124: * @return <code>true</code> if more
125: * elements available.
126: */
127: public boolean hasMoreElements() {
128: return index < roots.length;
129: }
130:
131: /**
132: * Gets the next element.
133: * @return next object in list
134: */
135: public Object nextElement() {
136: try {
137: return roots[index++];
138: } catch (ArrayIndexOutOfBoundsException e) {
139: throw new NoSuchElementException();
140: }
141: }
142: };
143: }
144:
145: /**
146: * Adds a root to the cache.
147: * @param root path to add to roots
148: */
149: static synchronized void addRoot(String root) {
150: RootCache cache = RootCache.getInstance();
151: if (!cache.isRoot(root)) {
152: cache.addRoot(root);
153: notifyListeners(FileSystemListener.ROOT_ADDED, root);
154: }
155: }
156:
157: /**
158: * Removes a root from the cache.
159: * @param root path to be removed
160: */
161: static synchronized void removeRoot(String root) {
162: RootCache cache = RootCache.getInstance();
163: if (cache.isRoot(root)) {
164: cache.removeRoot(root);
165: notifyListeners(FileSystemListener.ROOT_REMOVED, root);
166: }
167: }
168:
169: /**
170: * Notify registered listeners about mount/unmount event.
171: * @param event root added or removed event
172: * @param root pathname of the root file system
173: */
174: private static void notifyListeners(int event, String root) {
175: for (int i = 0; i < fileSystemListeners.size(); i++) {
176: try {
177: ((FileSystemListener) fileSystemListeners.elementAt(i))
178: .rootChanged(event, root);
179: } catch (Throwable t) {
180: t.printStackTrace();
181: }
182: }
183:
184: }
185:
186: /**
187: * Checks the read permission.
188: * @throws SecurityException if read is not allowed
189: */
190: private static void checkReadPermission() {
191: MIDletSuite suite = Scheduler.getScheduler().getMIDletSuite();
192:
193: try {
194: suite.checkForPermission(Permissions.FILE_CONNECTION_READ,
195: null);
196: } catch (InterruptedException ie) {
197: throw new SecurityException(
198: "Interrupted while trying to ask the user permission");
199: }
200: }
201: }
|