1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/* * @(#)CardTerminals.java 1.1 06/07/20 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.smartcardio; import java.util.*; /** * The set of terminals supported by a TerminalFactory. * This class allows applications to enumerate the available CardTerminals, * obtain a specific CardTerminal, or wait for the insertion or removal of * cards. * * <p>This class is multi-threading safe and can be used by multiple * threads concurrently. However, this object keeps track of the card * presence state of each of its terminals. Multiple objects should be used * if independent calls to {@linkplain #waitForChange} are required. * * <p>Applications can obtain instances of this class by calling * {@linkplain TerminalFactory#terminals}. * * @see TerminalFactory * @see CardTerminal * * @version 1.1, 07/20/06 * @since 1.6 * @author Andreas Sterbenz * @author JSR 268 Expert Group */ public abstract class CardTerminals { /** * Constructs a new CardTerminals object. * * <p>This constructor is called by subclasses only. Application should * call {@linkplain TerminalFactory#terminals} * to obtain a CardTerminals object. */ protected CardTerminals() { // empty } /** * Returns an unmodifiable list of all available terminals. * * @return an unmodifiable list of all available terminals. * * @throws CardException if the card operation failed */ public List<CardTerminal> list() throws CardException { return list(State.ALL); } /** * Returns an unmodifiable list of all terminals matching the specified * state. * * <p>If state is {@link State#ALL State.ALL}, this method returns * all CardTerminals encapsulated by this object. * If state is {@link State#CARD_PRESENT State.CARD_PRESENT} or * {@link State#CARD_ABSENT State.CARD_ABSENT}, it returns all * CardTerminals where a card is currently present or absent, respectively. * * <p>If state is {@link State#CARD_INSERTION State.CARD_INSERTION} or * {@link State#CARD_REMOVAL State.CARD_REMOVAL}, it returns all * CardTerminals for which an insertion (or removal, respectively) * was detected during the last call to {@linkplain #waitForChange}. * If <code>waitForChange()</code> has not been called on this object, * <code>CARD_INSERTION</code> is equivalent to <code>CARD_PRESENT</code> * and <code>CARD_REMOVAL</code> is equivalent to <code>CARD_ABSENT</code>. * For an example of the use of <code>CARD_INSERTION</code>, * see {@link #waitForChange}. * * @param state the State * @return an unmodifiable list of all terminals matching the specified * attribute. * * @throws NullPointerException if attr is null * @throws CardException if the card operation failed */ public abstract List<CardTerminal> list(State state) throws CardException; /** * Returns the terminal with the specified name or null if no such * terminal exists. * * @return the terminal with the specified name or null if no such * terminal exists. * * @throws NullPointerException if name is null */ public CardTerminal getTerminal(String name) { if (name == null) { throw new NullPointerException(); } try { for (CardTerminal terminal : list()) { if (terminal.getName().equals(name)) { return terminal; } } return null; } catch (CardException e) { return null; } } /** * Waits for card insertion or removal in any of the terminals of this * object. * * <p>This call is equivalent to calling * {@linkplain #waitForChange(long) waitForChange(0)}. * * @throws IllegalStateException if this <code>CardTerminals</code> * object does not contain any terminals * @throws CardException if the card operation failed */ public void waitForChange() throws CardException { waitForChange(0); } /** * Waits for card insertion or removal in any of the terminals of this * object or until the timeout expires. * * <p>This method examines each CardTerminal of this object. * If a card was inserted into or removed from a CardTerminal since the * previous call to <code>waitForChange()</code>, it returns * immediately. * Otherwise, or if this is the first call to <code>waitForChange()</code> * on this object, it blocks until a card is inserted into or removed from * a CardTerminal. * * <p>If <code>timeout</code> is greater than 0, the method returns after * <code>timeout</code> milliseconds even if there is no change in state. * In that case, this method returns <code>false</code>; otherwise it * returns <code>true</code>. * * <p>This method is often used in a loop in combination with * {@link #list(CardTerminals.State) list(State.CARD_INSERTION)}, * for example: * <pre> * TerminalFactory factory = ...; * CardTerminals terminals = factory.terminals(); * while (true) { * for (CardTerminal terminal : terminals.list(CARD_INSERTION)) { * // examine Card in terminal, return if it matches * } * terminals.waitForChange(); * }</pre> * * @param timeout if positive, block for up to <code>timeout</code> * milliseconds; if zero, block indefinitely; must not be negative * @return false if the method returns due to an expired timeout, * true otherwise. * * @throws IllegalStateException if this <code>CardTerminals</code> * object does not contain any terminals * @throws IllegalArgumentException if timeout is negative * @throws CardException if the card operation failed */ public abstract boolean waitForChange(long timeout) throws CardException; /** * Enumeration of attributes of a CardTerminal. * It is used as a parameter to the {@linkplain CardTerminals#list} method. * * @since 1.6 */ public static enum State { /** * All CardTerminals. */ ALL, /** * CardTerminals in which a card is present. */ CARD_PRESENT, /** * CardTerminals in which a card is not present. */ CARD_ABSENT, /** * CardTerminals for which a card insertion was detected during the * latest call to {@linkplain State#waitForChange waitForChange()} * call. */ CARD_INSERTION, /** * CardTerminals for which a card removal was detected during the * latest call to {@linkplain State#waitForChange waitForChange()} * call. */ CARD_REMOVAL, } }