/*
*
*
* Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program 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
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.cardreader;
import java.io.IOException;
import com.sun.midp.security.*;
import com.sun.midp.main.Configuration;
/**
* This is an internal class to hold a device configuration records.
*/
class DeviceRecord {
/** Class name. */
public String className;
/** Reference to device object. */
public CardDevice device;
}
/**
* This class represents card slot factory.
*/
public class SlotFactory {
/**
* Property which contains number of devices.
*/
private static final String DEVICE_NUMBER_PROP =
"com.sun.cardreader.deviceNumber";
/**
* Prefix of properties which contain class names.
*/
private static final String DEVICE_CLASS_PROP =
"com.sun.cardreader.deviceClass";
/**
* Reads devices and slots configuration.
*
* @throws CardDeviceException When the configuration is broken
* @throws IOException When the device creatiom failed
*/
public static void init() throws IOException, CardDeviceException {
synchronized (initialized) {
if (initialized.booleanValue()) {
return;
}
/*
* Get device number from system property.
* It is ok to have zero devices in configuration, we'll just
* do nothing in this case.
*/
int deviceNum = Configuration.getIntProperty(DEVICE_NUMBER_PROP, 0);
if (deviceNum < 0) {
throw new CardDeviceException("Number of devices must be > 0");
}
deviceRecords = new DeviceRecord[deviceNum];
/*
* Read device classes and create objects
* Also we count total slot number here
*/
CardDevice device = null;
int slotCount = 0;
for (int i = 0; i < deviceNum; i++) {
deviceRecords[i] = new DeviceRecord();
String pName = DEVICE_CLASS_PROP + Integer.toString(i);
deviceRecords[i].className = Configuration.getProperty(pName);
if (deviceRecords[i].className == null) {
throw new CardDeviceException("Class not found the device "
+ Integer.toString(i));
}
/* Create card device */
try {
Class cl = Class.forName(deviceRecords[i].className);
device = (CardDevice)(cl.newInstance());
deviceRecords[i].device = device;
}
catch (ClassNotFoundException e) {
throw new CardDeviceException("Class not found: " +
deviceRecords[i].className);
}
catch (InstantiationException ie) {
throw new IOException(ie.getMessage());
}
catch (IllegalAccessException iae) {
throw new IOException(iae.getMessage());
}
device.init();
device.setStartSlotNumber(slotCount);
slotCount += device.getSlotCount();
}
slots = new CardSlot[slotCount];
initialized = Boolean.TRUE;
}
}
/**
* Creates specified card slot for the specified device.
*
* @param slot Global slot number
* @param securityToken Security token for the slot
* @return CardSlot object or null if slot number is out of bounds
* @throws IOException If CardSlot creation failed
* @throws CardDeviceException If something wrong with the configuration
*/
public static CardSlot getCardSlot(int slot, SecurityToken securityToken)
throws IOException, CardDeviceException {
synchronized (initialized) {
if ((!initialized.booleanValue()) ||
(slot < 0) ||
(slot >= slots.length)) {
return null;
}
if (slots[slot] != null) {
return slots[slot];
} else {
/* Find device for the slot */
CardDevice device = null;
for (int i = 0; i < deviceRecords.length; i++) {
if (deviceRecords[i].device.checkSlotNumber(slot)) {
device = deviceRecords[i].device;
break;
}
}
if (device == null) {
/* Should not be here, paranoic check */
throw new CardDeviceException();
}
int localSlot = slot - device.getStartSlotNumber();
slots[slot] = new CardSlot(device, localSlot, securityToken);
return slots[slot];
}
}
}
/**
* Get total number of card slots.
*
* @return Total number of card slots even if they are not created yet
*/
public static int getCardSlotCount() {
synchronized (initialized) {
return slots.length;
}
}
/**
* Get total number of configured devices.
*
* @return Total number of configured devices
*/
public static int getCardDeviceCount() {
synchronized (initialized) {
return deviceRecords.length;
}
}
/**
* Checks if this slot is SAT slot.
*
* @param slot Slot number.
* @return <code>true</code> if the slot is dedicated for SAT,
* <code>false</code> otherwise
* @exception IOException If an error occured.
* @exception IllegalArgumentException if illegal slot number provided
*/
public static boolean isSatSlot(int slot) throws IOException {
synchronized (initialized) {
if ((!initialized.booleanValue()) ||
(slot < 0) ||
(slot >= slots.length)) {
throw new IllegalArgumentException("Slot does not exist");
}
if (slots[slot] != null) {
return slots[slot].isSAT();
} else {
/* Find device for the slot */
CardDevice device = null;
for (int i = 0; i < deviceRecords.length; i++) {
if (deviceRecords[i].device.checkSlotNumber(slot)) {
device = deviceRecords[i].device;
break;
}
}
if (device == null) {
/* Should not be here, paranoic check */
throw new IllegalArgumentException("Slot's device does not exist");
}
int localSlot = slot - device.getStartSlotNumber();
return device.isSatSlot(localSlot);
}
}
}
/**
* Device table, holds class names and object references.
*/
private static DeviceRecord deviceRecords[] = new DeviceRecord[0];
/**
* All slots created by the factory.
*/
private static CardSlot slots[] = new CardSlot[0];
/**
* Initialization flag. Also used in synchronized().
*/
private static Boolean initialized = Boolean.FALSE;
}
|