001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.cardreader;
028:
029: import java.io.IOException;
030: import com.sun.midp.security.*;
031: import com.sun.midp.main.Configuration;
032:
033: /**
034: * This is an internal class to hold a device configuration records.
035: */
036: class DeviceRecord {
037: /** Class name. */
038: public String className;
039: /** Reference to device object. */
040: public CardDevice device;
041: }
042:
043: /**
044: * This class represents card slot factory.
045: */
046: public class SlotFactory {
047: /**
048: * Property which contains number of devices.
049: */
050: private static final String DEVICE_NUMBER_PROP = "com.sun.cardreader.deviceNumber";
051: /**
052: * Prefix of properties which contain class names.
053: */
054: private static final String DEVICE_CLASS_PROP = "com.sun.cardreader.deviceClass";
055:
056: /**
057: * Reads devices and slots configuration.
058: *
059: * @throws CardDeviceException When the configuration is broken
060: * @throws IOException When the device creatiom failed
061: */
062: public static void init() throws IOException, CardDeviceException {
063: synchronized (initialized) {
064: if (initialized.booleanValue()) {
065: return;
066: }
067:
068: /*
069: * Get device number from system property.
070: * It is ok to have zero devices in configuration, we'll just
071: * do nothing in this case.
072: */
073: int deviceNum = Configuration.getIntProperty(
074: DEVICE_NUMBER_PROP, 0);
075: if (deviceNum < 0) {
076: throw new CardDeviceException(
077: "Number of devices must be > 0");
078: }
079:
080: deviceRecords = new DeviceRecord[deviceNum];
081:
082: /*
083: * Read device classes and create objects
084: * Also we count total slot number here
085: */
086: CardDevice device = null;
087: int slotCount = 0;
088:
089: for (int i = 0; i < deviceNum; i++) {
090: deviceRecords[i] = new DeviceRecord();
091:
092: String pName = DEVICE_CLASS_PROP + Integer.toString(i);
093: deviceRecords[i].className = Configuration
094: .getProperty(pName);
095: if (deviceRecords[i].className == null) {
096: throw new CardDeviceException(
097: "Class not found the device "
098: + Integer.toString(i));
099: }
100:
101: /* Create card device */
102: try {
103: Class cl = Class
104: .forName(deviceRecords[i].className);
105: device = (CardDevice) (cl.newInstance());
106: deviceRecords[i].device = device;
107: } catch (ClassNotFoundException e) {
108: throw new CardDeviceException("Class not found: "
109: + deviceRecords[i].className);
110: } catch (InstantiationException ie) {
111: throw new IOException(ie.getMessage());
112: } catch (IllegalAccessException iae) {
113: throw new IOException(iae.getMessage());
114: }
115: device.init();
116:
117: device.setStartSlotNumber(slotCount);
118: slotCount += device.getSlotCount();
119: }
120:
121: slots = new CardSlot[slotCount];
122: initialized = Boolean.TRUE;
123: }
124: }
125:
126: /**
127: * Creates specified card slot for the specified device.
128: *
129: * @param slot Global slot number
130: * @param securityToken Security token for the slot
131: * @return CardSlot object or null if slot number is out of bounds
132: * @throws IOException If CardSlot creation failed
133: * @throws CardDeviceException If something wrong with the configuration
134: */
135: public static CardSlot getCardSlot(int slot,
136: SecurityToken securityToken) throws IOException,
137: CardDeviceException {
138:
139: synchronized (initialized) {
140: if ((!initialized.booleanValue()) || (slot < 0)
141: || (slot >= slots.length)) {
142: return null;
143: }
144:
145: if (slots[slot] != null) {
146: return slots[slot];
147: } else {
148: /* Find device for the slot */
149: CardDevice device = null;
150: for (int i = 0; i < deviceRecords.length; i++) {
151: if (deviceRecords[i].device.checkSlotNumber(slot)) {
152: device = deviceRecords[i].device;
153: break;
154: }
155: }
156:
157: if (device == null) {
158: /* Should not be here, paranoic check */
159: throw new CardDeviceException();
160: }
161:
162: int localSlot = slot - device.getStartSlotNumber();
163: slots[slot] = new CardSlot(device, localSlot,
164: securityToken);
165:
166: return slots[slot];
167: }
168: }
169: }
170:
171: /**
172: * Get total number of card slots.
173: *
174: * @return Total number of card slots even if they are not created yet
175: */
176: public static int getCardSlotCount() {
177: synchronized (initialized) {
178: return slots.length;
179: }
180: }
181:
182: /**
183: * Get total number of configured devices.
184: *
185: * @return Total number of configured devices
186: */
187: public static int getCardDeviceCount() {
188: synchronized (initialized) {
189: return deviceRecords.length;
190: }
191: }
192:
193: /**
194: * Checks if this slot is SAT slot.
195: *
196: * @param slot Slot number.
197: * @return <code>true</code> if the slot is dedicated for SAT,
198: * <code>false</code> otherwise
199: * @exception IOException If an error occured.
200: * @exception IllegalArgumentException if illegal slot number provided
201: */
202: public static boolean isSatSlot(int slot) throws IOException {
203: synchronized (initialized) {
204: if ((!initialized.booleanValue()) || (slot < 0)
205: || (slot >= slots.length)) {
206: throw new IllegalArgumentException(
207: "Slot does not exist");
208: }
209:
210: if (slots[slot] != null) {
211: return slots[slot].isSAT();
212: } else {
213: /* Find device for the slot */
214: CardDevice device = null;
215: for (int i = 0; i < deviceRecords.length; i++) {
216: if (deviceRecords[i].device.checkSlotNumber(slot)) {
217: device = deviceRecords[i].device;
218: break;
219: }
220: }
221:
222: if (device == null) {
223: /* Should not be here, paranoic check */
224: throw new IllegalArgumentException(
225: "Slot's device does not exist");
226: }
227:
228: int localSlot = slot - device.getStartSlotNumber();
229: return device.isSatSlot(localSlot);
230: }
231: }
232: }
233:
234: /**
235: * Device table, holds class names and object references.
236: */
237: private static DeviceRecord deviceRecords[] = new DeviceRecord[0];
238:
239: /**
240: * All slots created by the factory.
241: */
242: private static CardSlot slots[] = new CardSlot[0];
243:
244: /**
245: * Initialization flag. Also used in synchronized().
246: */
247: private static Boolean initialized = Boolean.FALSE;
248: }
|