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.satsa.acl;
028:
029: import com.sun.midp.lcdui.DisplayEventHandler;
030: import com.sun.midp.lcdui.DisplayEventHandlerFactory;
031: import com.sun.midp.security.SecurityToken;
032:
033: import com.sun.midp.i18n.Resource;
034: import com.sun.midp.i18n.ResourceConstants;
035:
036: import com.sun.midp.midlet.MIDletEventConsumer;
037: import com.sun.midp.midlet.MIDletPeer;
038:
039: import javax.microedition.lcdui.*;
040:
041: /** Implements PIN entry dialog. */
042: public class PINEntryDialog implements CommandListener {
043:
044: /** Answer that indicates that the dialog was cancelled. */
045: private static final int CANCELLED = -1;
046: /** Answer that indicates successful completion. */
047: private static final int CONFIRMED = 1;
048:
049: /** Caches the display manager reference. */
050: private DisplayEventHandler displayEventHandler;
051:
052: /** Command object for "OK" command. */
053: private Command okCmd = new Command(Resource
054: .getString(ResourceConstants.OK), Command.OK, 1);
055:
056: /** Command object for "Cancel" command. */
057: private Command cancelCmd = new Command(Resource
058: .getString(ResourceConstants.CANCEL), Command.CANCEL, 1);
059:
060: /** Holds the preempt token so the form can end. */
061: private Object preemptToken;
062:
063: /** Holds the answer to the security question. */
064: private int answer = CANCELLED;
065:
066: /** PIN entry text field. */
067: private TextField tf1;
068: /** PIN entry text field. */
069: private TextField tf2;
070: /** Attributes of the 1st PIN. */
071: private PINAttributes pin1;
072: /** Attributes of the 2nd PIN. */
073: private PINAttributes pin2;
074: /** 1st PIN data. */
075: private byte[] data1;
076: /** 2nd PIN data. */
077: private byte[] data2;
078:
079: /**
080: * Construct PIN dialog.
081: *
082: * @param token security token with the permission to peempt the
083: * foreground display
084: * @param action PIN entry operation identifier.
085: * @param attr1 1st PIN attributes.
086: * @param attr2 2nd PIN attributes.
087: * @exception InterruptedException if another thread interrupts the
088: * calling thread while this method is waiting to preempt the
089: * display.
090: */
091: public PINEntryDialog(SecurityToken token, int action,
092: PINAttributes attr1, PINAttributes attr2)
093: throws InterruptedException {
094:
095: String title = null;
096:
097: String label1 = attr1.label;
098: String label2 = null;
099: pin1 = attr1;
100: pin2 = null;
101:
102: switch (action) {
103: case ACLPermissions.CMD_VERIFY: {
104: // "PIN verification"
105: title = Resource
106: .getString(ResourceConstants.JSR177_PINDIALOG_TITLE_VERIFY);
107: break;
108: }
109: case ACLPermissions.CMD_CHANGE: {
110: // "Change PIN"
111: title = Resource
112: .getString(ResourceConstants.JSR177_PINDIALOG_TITLE_CHANGE);
113: // "New value" -> "Enter new PIN"
114: label2 = Resource
115: .getString(ResourceConstants.JSR177_PINDIALOG_ENTERPIN);
116: pin2 = attr1;
117: break;
118: }
119: case ACLPermissions.CMD_DISABLE: {
120: // "Disable PIN"
121: title = Resource
122: .getString(ResourceConstants.JSR177_PINDIALOG_TITLE_DISABLE);
123: break;
124: }
125: case ACLPermissions.CMD_ENABLE: {
126: // "Enable PIN";
127: title = Resource
128: .getString(ResourceConstants.JSR177_PINDIALOG_TITLE_ENABLE);
129: break;
130: }
131: case ACLPermissions.CMD_UNBLOCK: {
132: // "Unblock PIN"
133: title = Resource
134: .getString(ResourceConstants.JSR177_PINDIALOG_TITLE_UNBLOCK);
135: label1 = attr2.label;
136: label2 = attr1.label
137: + " - "
138: +
139: // "new value"
140: Resource
141: .getString(ResourceConstants.JSR177_PINDIALOG_NEWVALUE);
142: pin1 = attr2;
143: pin2 = attr1;
144: break;
145: }
146: }
147:
148: Form form = new Form(title);
149:
150: int flags = TextField.PASSWORD;
151: if (pin1.isNumeric()) {
152: flags |= TextField.NUMERIC;
153: }
154: tf1 = new TextField(label1, "", pin1.getMaxLength(), flags);
155: form.append(tf1);
156:
157: if (pin2 != null) {
158:
159: flags = TextField.SENSITIVE | TextField.NON_PREDICTIVE;
160: if (pin2.isNumeric()) {
161: flags |= TextField.NUMERIC;
162: }
163: tf2 = new TextField(label2, "", pin2.getMaxLength(), flags);
164: form.append(tf2);
165:
166: }
167:
168: form.addCommand(cancelCmd);
169: form.addCommand(okCmd);
170: form.setCommandListener(this );
171: if (displayEventHandler == null) {
172: displayEventHandler = DisplayEventHandlerFactory
173: .getDisplayEventHandler(token);
174: }
175: preemptToken = displayEventHandler.preemptDisplay(form, true);
176: }
177:
178: /**
179: * Waits for the user's answer.
180: * @return user's answer
181: */
182: public int waitForAnswer() {
183: synchronized (this ) {
184: if (preemptToken == null) {
185: return CANCELLED;
186: }
187:
188: try {
189: wait();
190: } catch (Throwable t) {
191: return CANCELLED;
192: }
193:
194: return answer;
195: }
196: }
197:
198: /**
199: * Sets the user's answer and notifies waitForAnswer and
200: * ends the form.
201: * @param theAnswer user's answer or CANCEL if system cancelled the
202: * screen
203: */
204: private void setAnswer(int theAnswer) {
205: synchronized (this ) {
206: answer = theAnswer;
207: displayEventHandler.donePreempting(preemptToken);
208: notify();
209: }
210:
211: }
212:
213: /**
214: * Respond to a command issued on form.
215: * @param c command activiated by the user
216: * @param s the Displayable the command was on.
217: */
218: public void commandAction(Command c, Displayable s) {
219: if (c == okCmd) {
220: if (!checkInput()) {
221: return;
222: }
223: setAnswer(CONFIRMED);
224: } else {
225: setAnswer(CANCELLED);
226: }
227:
228: }
229:
230: /**
231: * Verifies that the values entered are acceptable.
232: * @return true if the values entered are acceptable.
233: */
234: private boolean checkInput() {
235:
236: if (tf1.getString().trim().equals("")) {
237: return false;
238: }
239:
240: data1 = pin1.transform(tf1.getString());
241: if (data1 == null) {
242: // PIN can't be formatted, pass empty PIN to update counter
243: data1 = new byte[8];
244: }
245:
246: if (pin2 != null) {
247: data2 = pin2.transform(tf2.getString());
248: if (data2 == null) {
249: tf2.setString("");
250: return false;
251: }
252: } else {
253: data2 = null;
254: }
255: return true;
256: }
257:
258: /**
259: * Get the entered values.
260: * @return null if PIN entry was cancelled by user, otherwise an array
261: * containing PIN value(s).
262: */
263: public Object[] getPINs() {
264:
265: if (answer == CANCELLED) {
266: return null;
267: }
268:
269: if (pin2 == null) {
270: return new Object[] { data1 };
271: }
272:
273: return new Object[] { data1, data2 };
274: }
275: }
|